]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/messages.c
Replace relevant direct seteuid() calls with calls to (un)become_root()
[netatalk.git] / etc / afpd / messages.c
1 /*
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * All Rights Reserved.  See COPYRIGHT.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif /* HAVE_CONFIG_H */
9
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <stdlib.h>
15 #include <atalk/afp.h>
16 #include <atalk/dsi.h>
17 #include <atalk/util.h>
18 #include <atalk/unix.h>
19 #include <atalk/logger.h>
20 #include <atalk/globals.h>
21
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[MAXPATHLEN] = "";
28 static char localized_message[MAXPATHLEN] = "";
29
30 void setmessage(const char *message)
31 {
32     strlcpy(servermesg, message, MAXMESGSIZE);
33 }
34
35 void readmessage(AFPObj *obj)
36 {
37     /* Read server message from file defined as SERVERTEXT */
38 #ifdef SERVERTEXT
39     FILE *message;
40     char * filename;
41     unsigned int i; 
42     int rc;
43     static int c;
44     uint32_t maxmsgsize;
45
46     maxmsgsize = MIN(MAX(obj->dsi->attn_quantum, MAXMESGSIZE), MAXPATHLEN);
47
48     i=0;
49     /* Construct file name SERVERTEXT/message.[pid] */
50     if ( NULL == (filename=(char*) malloc(sizeof(SERVERTEXT)+15)) ) {
51         LOG(log_error, logtype_afpd, "readmessage: malloc: %s", strerror(errno) );
52         return;
53     }
54
55     sprintf(filename, "%s/message.%d", SERVERTEXT, getpid());
56
57 #ifdef DEBUG
58     LOG(log_debug9, logtype_afpd, "Reading file %s ", filename);
59 #endif 
60
61     message=fopen(filename, "r");
62     if (message==NULL) {
63         /* try without the process id */
64         sprintf(filename, "%s/message", SERVERTEXT);
65         message=fopen(filename, "r");
66     }
67
68     /* if either message.pid or message exists */
69     if (message!=NULL) {
70         /* added while loop to get characters and put in servermesg */
71         while ((( c=fgetc(message)) != EOF) && (i < (maxmsgsize - 1))) {
72             if ( c == '\n')  c = ' ';
73             servermesg[i++] = c;
74         }
75         servermesg[i] = 0;
76
77         /* cleanup */
78         fclose(message);
79
80         become_root();
81
82         if ((rc = unlink(filename)) != 0)
83             LOG(log_error, logtype_afpd, "File '%s' could not be deleted", strerror(errno));
84
85         unbecome_root();
86
87         if (rc < 0) {
88             LOG(log_error, logtype_afpd, "Error deleting %s: %s", filename, strerror(rc));
89         }
90 #ifdef DEBUG
91         else {
92             LOG(log_debug9, logtype_afpd, "Deleted %s", filename);
93         }
94
95         LOG(log_debug9, logtype_afpd, "Set server message to \"%s\"", servermesg);
96 #endif
97     }
98     free(filename);
99 #endif /* SERVERTEXT */
100 }
101
102 int afp_getsrvrmesg(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
103 {
104     char *message;
105     uint16_t type, bitmap;
106     uint16_t msgsize;
107     size_t outlen = 0;
108     size_t msglen = 0;
109     int utf8 = 0;
110
111     *rbuflen = 0;
112
113     msgsize = MAX(obj->dsi->attn_quantum, MAXMESGSIZE);
114
115     memcpy(&type, ibuf + 2, sizeof(type));
116     memcpy(&bitmap, ibuf + 4, sizeof(bitmap));
117
118     message = servermesg;
119     switch (ntohs(type)) {
120     case AFPMESG_LOGIN: /* login */
121         /* at least TIGER loses server messages
122          * if it receives a server msg attention before
123          * it has asked the login msg...
124          * Workaround: concatenate the two if any, ugly.
125          */
126         if (obj->options.loginmesg) {
127             if (*message)
128                 strlcat(message, " - ", MAXMESGSIZE);
129             strlcat(message, obj->options.loginmesg, MAXMESGSIZE);
130         }
131         break;
132     case AFPMESG_SERVER: /* server */
133         break;
134     default:
135         return AFPERR_BITMAP;
136     }
137
138     /* output format:
139      * message type:   2 bytes
140      * bitmap:         2 bytes
141      * message length: 1 byte ( 2 bytes for utf8)
142      * message:        up to 199 bytes (dsi attn_quantum for utf8)
143      */
144     memcpy(rbuf, &type, sizeof(type));
145     rbuf += sizeof(type);
146     *rbuflen += sizeof(type);
147     memcpy(rbuf, &bitmap, sizeof(bitmap));
148     rbuf += sizeof(bitmap);
149     *rbuflen += sizeof(bitmap);
150
151     utf8 = ntohs(bitmap) & 2; 
152     msglen = strlen(message);
153     if (msglen > msgsize)
154         msglen = msgsize;
155
156     if (msglen) { 
157         if ( (size_t)-1 == (outlen = convert_string(obj->options.unixcharset, utf8?CH_UTF8_MAC:obj->options.maccharset,
158                                                     message, msglen, localized_message, msgsize)) )
159         {
160             memcpy(rbuf+((utf8)?2:1), message, msglen); /*FIXME*/
161             outlen = msglen;
162         }
163         else
164         {
165             memcpy(rbuf+((utf8)?2:1), localized_message, outlen);
166         }
167     }
168     
169     if ( utf8 ) {
170         /* UTF8 message, 2 byte length */
171         msgsize = htons(outlen);
172         memcpy(rbuf, &msgsize, sizeof(msgsize));
173         *rbuflen += sizeof(msgsize);
174     }
175     else {
176         *rbuf = outlen;
177         *rbuflen += 1;
178     }
179     *rbuflen += outlen;
180     *message = 0;
181     return AFP_OK;
182 }