]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/messages.c
0918e421c573a386f17aac768b93a00289d04a96
[netatalk.git] / etc / afpd / messages.c
1 /*
2  * $Id: messages.c,v 1.17 2003-06-02 06:54:23 didg Exp $
3  *
4  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
5  * All Rights Reserved.  See COPYRIGHT.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <atalk/afp.h>
17 #include <atalk/logger.h>
18 #ifdef HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif /* HAVE_UNISTD_H */
21 #include "globals.h"
22 #include "misc.h"
23
24 #define MAXMESGSIZE 199
25
26 /* this is only used by afpd children, so it's okay. */
27 static char servermesg[MAXMESGSIZE] = "";
28
29 void setmessage(const char *message)
30 {
31     strncpy(servermesg, message, MAXMESGSIZE);
32 }
33
34 void readmessage(void)
35 {
36     /* Read server message from file defined as SERVERTEXT */
37 #ifdef SERVERTEXT
38     FILE *message;
39     char * filename;
40     int i, rc;
41     static int c;
42     uid_t euid;
43
44     i=0;
45     /* Construct file name SERVERTEXT/message.[pid] */
46     if ( NULL == (filename=(char*) malloc(sizeof(SERVERTEXT)+15)) ) {
47         LOG(log_error, logtype_afpd, "readmessage: malloc: %s", strerror(errno) );
48         return;
49     }
50
51     sprintf(filename, "%s/message.%d", SERVERTEXT, getpid());
52
53 #ifdef DEBUG
54     LOG(log_debug, logtype_afpd, "Reading file %s ", filename);
55 #endif /* DEBUG */
56
57     message=fopen(filename, "r");
58     if (message==NULL) {
59         LOG(log_info, logtype_afpd, "Unable to open file %s", filename);
60         sprintf(filename, "%s/message", SERVERTEXT);
61         message=fopen(filename, "r");
62     }
63
64     /* if either message.pid or message exists */
65     if (message!=NULL) {
66         /* added while loop to get characters and put in servermesg */
67         while ((( c=fgetc(message)) != EOF) && (i < (MAXMESGSIZE - 1))) {
68             if ( c == '\n')  c = ' ';
69             servermesg[i++] = c;
70         }
71         servermesg[i] = 0;
72
73         /* cleanup */
74         fclose(message);
75
76         /* Save effective uid and switch to root to delete file. */
77         /* Delete will probably fail otherwise, but let's try anyways */
78         euid = geteuid();
79         if (seteuid(0) < 0) {
80             LOG(log_error, logtype_afpd, "Could not switch back to root: %s",
81                                 strerror(errno));
82         }
83
84         rc = unlink(filename);
85
86         /* Drop privs again, failing this is very bad */
87         if (seteuid(euid) < 0) {
88             LOG(log_error, logtype_afpd, "Could not switch back to uid %d: %s", euid, strerror(errno));
89         }
90
91         if (rc < 0) {
92             LOG(log_error, logtype_afpd, "Error deleting %s: %s", filename, strerror(rc));
93         }
94 #ifdef DEBUG
95         else {
96             LOG(log_info, logtype_afpd, "Deleted %s", filename);
97         }
98
99         LOG(log_info, logtype_afpd, "Set server message to \"%s\"", servermesg);
100 #endif /* DEBUG */
101     }
102     free(filename);
103 #endif /* SERVERTEXT */
104 }
105
106 int afp_getsrvrmesg(obj, ibuf, ibuflen, rbuf, rbuflen)
107 AFPObj *obj;
108 char *ibuf, *rbuf;
109 int ibuflen, *rbuflen;
110 {
111     char *message;
112     u_int16_t type, bitmap;
113
114     memcpy(&type, ibuf + 2, sizeof(type));
115     memcpy(&bitmap, ibuf + 4, sizeof(bitmap));
116
117     switch (ntohs(type)) {
118     case AFPMESG_LOGIN: /* login */
119         message = obj->options.loginmesg;
120         break;
121     case AFPMESG_SERVER: /* server */
122         message = servermesg;
123         break;
124     default:
125         *rbuflen = 0;
126         return AFPERR_BITMAP;
127     }
128
129     /* output format:
130      * message type:   2 bytes
131      * bitmap:         2 bytes
132      * message length: 1 byte
133      * message:        up to 199 bytes
134      */
135     memcpy(rbuf, &type, sizeof(type));
136     rbuf += sizeof(type);
137     memcpy(rbuf, &bitmap, sizeof(bitmap));
138     rbuf += sizeof(bitmap);
139     *rbuflen = strlen(message);
140     if (*rbuflen > MAXMESGSIZE)
141         *rbuflen = MAXMESGSIZE;
142     *rbuf++ = *rbuflen;
143     memcpy(rbuf, message, *rbuflen);
144
145     *rbuflen += 5;
146
147     return AFP_OK;
148 }