~ubuntu-branches/ubuntu/trusty/dhcpcd/trusty-security

« back to all changes in this revision

Viewing changes to dhcpcd.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Kelley
  • Date: 2005-09-30 02:21:51 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050930022151-vq3xlcazj0bdpyf4
Tags: 1:2.0.0-2
Clear out /etc/dhcpc/resolv.conf and /var/lib/dhcpc/* 
during purge. (closes: #330515)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * dhcpcd - DHCP client daemon -
3
 
 * Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
4
 
 * Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
5
 
 * 
6
 
 * dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
7
 
 *
8
 
 * This is free software; you can redistribute it and/or modify it
9
 
 * under the terms of the GNU General Public License as published by
10
 
 * the Free Software Foundation; either version 2 of the License, or
11
 
 * (at your option) any later version.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful, but
14
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
 
 * See the GNU General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program; if not, write to the Free Software
20
 
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
 */
22
 
 
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
#include <string.h>
26
 
#include <syslog.h>
27
 
#include <unistd.h>
28
 
#include <fcntl.h>
29
 
#include <sys/stat.h>
30
 
#include <net/if.h>
31
 
#include <netinet/in.h>
32
 
#include <arpa/inet.h>
33
 
#include <errno.h>
34
 
#include <ctype.h>
35
 
#include "pathnames.h"
36
 
#include "client.h"
37
 
#include "signals.h"
38
 
#include "udpipgen.h"
39
 
 
40
 
struct in_addr  inform_ipaddr,default_router;
41
 
char            *ProgramName    =       NULL;
42
 
char            **ProgramEnviron=       NULL;
43
 
char            *IfName         =       DEFAULT_IFNAME;
44
 
char            *IfNameExt      =       DEFAULT_IFNAME;
45
 
int             IfName_len      =       DEFAULT_IFNAME_LEN;
46
 
int             IfNameExt_len   =       DEFAULT_IFNAME_LEN;
47
 
char            *HostName       =       NULL;
48
 
int             HostName_len    =       0;
49
 
char            *Cfilename      =       NULL;
50
 
unsigned char   *ClassID        =       NULL;
51
 
int             ClassID_len     =       0;
52
 
unsigned char   *ClientID       =       NULL;
53
 
int             ClientID_len    =       0;
54
 
void            *(*currState)() =       &dhcpReboot;
55
 
int             DebugFlag       =       0;
56
 
int             BeRFC1541       =       0;
57
 
unsigned        LeaseTime       =       DEFAULT_LEASETIME;
58
 
int             ReplResolvConf  =       1;
59
 
int             ReplNISConf     =       1;
60
 
int             ReplNTPConf     =       1;
61
 
int             SetDomainName   =       0;
62
 
int             SetHostName     =       0;
63
 
int             BroadcastResp   =       0;
64
 
time_t          TimeOut         =       DEFAULT_TIMEOUT;
65
 
int             magic_cookie    =       0;
66
 
unsigned short  dhcpMsgSize     =       0;
67
 
unsigned        nleaseTime      =       0;
68
 
int             DoCheckSum      =       0;
69
 
int             TestCase        =       0;
70
 
int             SendSecondDiscover      =       0;
71
 
int             Window          =       0;
72
 
char            *ConfigDir      =       CONFIG_DIR;
73
 
int             SetDHCPDefaultRoutes=   1;
74
 
int             Persistent      =       0;
75
 
#if 0
76
 
unsigned char   ClientMACaddr[ETH_ALEN];
77
 
int             ClientMACaddr_ind =     0;
78
 
#endif
79
 
/*****************************************************************************/
80
 
void print_version()
81
 
{
82
 
  fprintf(stderr,"\
83
 
DHCP Client Daemon v."VERSION"\n\
84
 
Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>\n\
85
 
Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>\n\
86
 
Location: http://www.phystech.com/download/\n");
87
 
}
88
 
/*****************************************************************************/
89
 
void checkIfAlreadyRunning()
90
 
{
91
 
  int o;
92
 
  char pidfile[64];
93
 
  snprintf(pidfile,sizeof(pidfile),PID_FILE_PATH,ConfigDir,IfNameExt);
94
 
  o=open(pidfile,O_RDONLY);
95
 
  if ( o == -1 ) return;
96
 
  close(o);
97
 
  fprintf(stderr,"\
98
 
****  %s: already running\n\
99
 
****  %s: if not then delete %s file\n",ProgramName,ProgramName,pidfile);
100
 
  exit(1);
101
 
}
102
 
/*****************************************************************************/
103
 
int main(argn,argc,argv)
104
 
int argn;
105
 
char *argc[],*argv[];
106
 
{
107
 
  int killFlag          =       0;
108
 
  int versionFlag       =       0;
109
 
  int s                 =       1;
110
 
  int k                 =       1;
111
 
  int i                 =       1;
112
 
  int j;
113
 
 
114
 
/*
115
 
 * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else.
116
 
 * This way we can close 0, 1, 2 after forking the daemon without clobbering
117
 
 * a fd that we are using (such as our sockets). This is necessary if
118
 
 * this program is run from init scripts where 0, 1, and/or 2 may be closed.
119
 
 */
120
 
 j=open("/dev/null",O_RDWR);
121
 
 while ( j < 2 && j >= 0 ) j = dup(j);
122
 
 if ( j > 2 ) close(j);
123
 
 
124
 
  if ( geteuid() )
125
 
    {
126
 
      fprintf(stderr,"****  %s: not a superuser\n",argc[0]);
127
 
      exit(1);
128
 
    }
129
 
 
130
 
  while ( argc[i] )
131
 
    if ( argc[i][0]=='-' )
132
 
prgs: switch ( argc[i][s] )
133
 
        {
134
 
          case 0:
135
 
            i++;
136
 
            s=1;
137
 
            break;
138
 
          case 'p':
139
 
            s++;
140
 
            Persistent = 1;
141
 
            goto prgs;
142
 
          case 'k':
143
 
            s++;
144
 
            killFlag=SIGHUP;
145
 
            goto prgs;
146
 
          case 'n':
147
 
            s++;
148
 
            killFlag=SIGALRM;
149
 
            goto prgs;
150
 
          case 'd':
151
 
            s++;
152
 
            DebugFlag=1;
153
 
            goto prgs;
154
 
          case 'r':
155
 
            s++;
156
 
            BeRFC1541=1;
157
 
            goto prgs;
158
 
          case 'D':
159
 
            s++;
160
 
            SetDomainName=1;
161
 
            goto prgs;
162
 
          case 'H':
163
 
            s++;
164
 
            SetHostName=1;
165
 
            goto prgs;
166
 
          case 'R':
167
 
            s++;
168
 
            ReplResolvConf=0;
169
 
            goto prgs;
170
 
          case 'Y':
171
 
            s++;
172
 
            ReplNISConf=0;
173
 
            goto prgs;
174
 
          case 'N':
175
 
            s++;
176
 
            ReplNTPConf=0;
177
 
            goto prgs;
178
 
          case 'V':
179
 
            s++;
180
 
            versionFlag=1;
181
 
            goto prgs;
182
 
          case 'c':
183
 
            if ( argc[i][s+1] ) goto usage;
184
 
            i++;
185
 
            Cfilename=argc[i++];
186
 
            if ( Cfilename == NULL || Cfilename[0] == '-' ) goto usage;
187
 
            s=1;
188
 
            break;
189
 
          case 'L':
190
 
            if ( argc[i][s+1] ) goto usage;
191
 
            i++;
192
 
            ConfigDir=argc[i++];
193
 
            if ( ConfigDir == NULL || ConfigDir[0] != '/' ) goto usage;
194
 
            s=1;
195
 
            break;
196
 
#if 0
197
 
          case 'M':
198
 
            if ( argc[i][s+1] ) goto usage;
199
 
            i++;
200
 
            if ( argc[i] == NULL ) goto usage;
201
 
            if ( isxdigit(argc[i][0]) && isxdigit(argc[i][1]) && argc[i][2] == ':' )
202
 
              ClientMACaddr[0] = 16*(argc[i][0]>64?(toupper(argc[i][0])-55):(argc[i][0]-48)) +
203
 
              (argc[i][1]>64?(toupper(argc[i][1])-55):(argc[i][1]-48));
204
 
            else
205
 
              goto usage;
206
 
            if ( isxdigit(argc[i][3]) && isxdigit(argc[i][4]) && argc[i][5] == ':' )
207
 
              ClientMACaddr[1] = 16*(argc[i][3]>64?(toupper(argc[i][3])-55):(argc[i][3]-48)) +
208
 
              (argc[i][4]>64?(toupper(argc[i][4])-55):(argc[i][4]-48));
209
 
            else
210
 
              goto usage;
211
 
            if ( isxdigit(argc[i][6]) && isxdigit(argc[i][7]) && argc[i][8] == ':' )
212
 
              ClientMACaddr[2] = 16*(argc[i][6]>64?(toupper(argc[i][6])-55):(argc[i][6]-48)) +
213
 
              (argc[i][7]>64?(toupper(argc[i][7])-55):(argc[i][7]-48));
214
 
            else
215
 
              goto usage;
216
 
            if ( isxdigit(argc[i][9]) && isxdigit(argc[i][10]) && argc[i][11] == ':' )
217
 
              ClientMACaddr[3] = 16*(argc[i][9]>64?(toupper(argc[i][9])-55):(argc[i][9]-48)) +
218
 
              (argc[i][10]>64?(toupper(argc[i][10])-55):(argc[i][10]-48));
219
 
            else
220
 
              goto usage;
221
 
            if ( isxdigit(argc[i][12]) && isxdigit(argc[i][13]) && argc[i][14] == ':' )
222
 
              ClientMACaddr[4] = 16*(argc[i][12]>64?(toupper(argc[i][12])-55):(argc[i][12]-48)) +
223
 
              (argc[i][13]>64?(toupper(argc[i][13])-55):(argc[i][13]-48));
224
 
            else
225
 
              goto usage;
226
 
            if ( isxdigit(argc[i][15]) && isxdigit(argc[i][16]) )
227
 
              ClientMACaddr[5] = 16*(argc[i][15]>64?(toupper(argc[i][15])-55):(argc[i][15]-48)) +
228
 
              (argc[i][16]>64?(toupper(argc[i][16])-55):(argc[i][16]-48));
229
 
            else
230
 
              goto usage;
231
 
            s=1;
232
 
            i++;
233
 
            ClientMACaddr_ind=1;
234
 
            break;
235
 
#endif
236
 
          case 'i':
237
 
            if ( argc[i][s+1] ) goto usage;
238
 
            i++;
239
 
            ClassID=argc[i++];
240
 
            if ( ClassID == NULL || ClassID[0] == '-' ) goto usage;
241
 
            s=1;
242
 
            if ( (ClassID_len=strlen(ClassID)) < CLASS_ID_MAX_LEN+1 ) break;
243
 
            fprintf(stderr,"****  %s: too long ClassID string: strlen=%d\n",
244
 
            argc[0],ClassID_len);
245
 
            goto usage;
246
 
          case 'I':
247
 
            if ( argc[i][s+1] ) goto usage;
248
 
            i++;
249
 
            ClientID=argc[i++];
250
 
            if ( ClientID == NULL || ClientID[0] == '-' ) goto usage;
251
 
            s=1;
252
 
            if ( (ClientID_len=strlen(ClientID)) < CLIENT_ID_MAX_LEN+1 ) break;
253
 
            fprintf(stderr,"****  %s: too long ClientID string: strlen=%d\n",
254
 
            argc[0],ClientID_len);
255
 
            goto usage;
256
 
          case 'h':
257
 
            if ( argc[i][s+1] ) goto usage;
258
 
            i++;
259
 
            HostName=argc[i++];
260
 
            if ( HostName == NULL || HostName[0] == '-' ) goto usage;
261
 
            s=1;
262
 
            if ( (HostName_len=strlen(HostName)+1) < HOSTNAME_MAX_LEN ) break;
263
 
            fprintf(stderr,"****  %s: too long HostName string: strlen=%d\n",
264
 
            argc[0],HostName_len);
265
 
            break;
266
 
          case 't':
267
 
            if ( argc[i][s+1] ) goto usage;
268
 
            i++;
269
 
            if ( argc[i] )
270
 
              TimeOut=atol(argc[i++]);
271
 
            else
272
 
              goto usage;
273
 
            s=1;
274
 
            if ( TimeOut >= 0 ) break;
275
 
            goto usage;
276
 
          case 'w':
277
 
            if ( argc[i][s+1] ) goto usage;
278
 
            i++;
279
 
            if ( argc[i] )
280
 
              Window=atol(argc[i++]);
281
 
            else
282
 
              goto usage;
283
 
            s=1;
284
 
            if ( Window >= 0 ) break;
285
 
            goto usage;
286
 
          case 's':
287
 
            if ( argc[i][s+1] ) goto usage;
288
 
            i++;
289
 
            if ( argc[i] && inet_aton(argc[i],&inform_ipaddr) )
290
 
              i++;
291
 
            else
292
 
              memset(&inform_ipaddr,0,sizeof(inform_ipaddr));
293
 
            currState = &dhcpInform;
294
 
            s=1;
295
 
            break;
296
 
          case 'G':
297
 
            if ( argc[i][s+1] ) goto usage;
298
 
            SetDHCPDefaultRoutes=0;
299
 
            i++;
300
 
            if ( argc[i] && inet_aton(argc[i],&default_router) )
301
 
              i++;
302
 
            else
303
 
              memset(&default_router,0,sizeof(default_router));
304
 
            s=1;
305
 
            break;
306
 
          case 'B':
307
 
            s++;
308
 
            BroadcastResp=1;
309
 
            goto prgs;
310
 
          case 'C':
311
 
            s++;
312
 
            DoCheckSum=1;
313
 
            goto prgs;
314
 
          case 'T':
315
 
            s++;
316
 
            TestCase=1;
317
 
            goto prgs;
318
 
          case 'S':
319
 
            s++;
320
 
            SendSecondDiscover=1;
321
 
            goto prgs;
322
 
          case 'l':
323
 
            if ( argc[i][s+1] ) goto usage;
324
 
            i++;
325
 
            if ( argc[i] )
326
 
              LeaseTime=atol(argc[i++]);
327
 
            else
328
 
              goto usage;
329
 
            s=1;
330
 
            if ( LeaseTime > 0 ) break;
331
 
          default:
332
 
usage:      print_version();
333
 
            fprintf(stderr,
334
 
"Usage: dhcpcd [-dknprBCDHNRSTY] [-l leasetime] [-h hostname] [-t timeout]\n\
335
 
       [-i vendorClassID] [-I ClientID] [-c filename] [-s [ipaddr]]\n\
336
 
       [-w windowsize] [-L ConfigDir] [-G [gateway]] [interface]\n");
337
 
            exit(1);
338
 
        }
339
 
    else
340
 
      argc[k++]=argc[i++];
341
 
  if ( k > 1 )
342
 
    {
343
 
      if ( (IfNameExt_len=strlen(argc[1])) > IFNAMSIZ ) goto usage;
344
 
      IfNameExt=argc[1];
345
 
      IfName=IfNameExt;
346
 
      IfName_len=IfNameExt_len;
347
 
      s=0;
348
 
      while ( IfNameExt[s] )
349
 
        if ( IfNameExt[s] == ':' )
350
 
          {
351
 
            IfName=(char *)malloc(s+1);
352
 
            memcpy(IfName,IfNameExt,s);
353
 
            IfName[s]=0;
354
 
            IfName_len=s;
355
 
            break;
356
 
          }
357
 
        else
358
 
          s++;
359
 
    }
360
 
  ProgramName=argc[0];
361
 
  ProgramEnviron=argv;
362
 
  umask(022);
363
 
  if ( killFlag ) killPid(killFlag);
364
 
  if ( ! TestCase ) checkIfAlreadyRunning();
365
 
  if ( versionFlag ) print_version();
366
 
  openlog(PROGRAM_NAME,LOG_PID|(DebugFlag?LOG_CONS:0),LOG_LOCAL0);
367
 
  signalSetup();
368
 
  if ( mkdir(ConfigDir,S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) && errno != EEXIST )
369
 
    {
370
 
      syslog(LOG_ERR,"mkdir(\"%s\",0): %m\n",ConfigDir);
371
 
      exit(1);
372
 
    }
373
 
  magic_cookie = htonl(MAGIC_COOKIE);
374
 
  dhcpMsgSize = htons(sizeof(dhcpMessage)+sizeof(udpiphdr));
375
 
  nleaseTime = htonl(LeaseTime);
376
 
  if (TimeOut != 0)
377
 
    alarm(TimeOut);
378
 
  do
379
 
    if ( (currState=(void *(*)())currState()) == NULL ) exit(1);
380
 
  while ( currState != &dhcpBound );
381
 
#if 0
382
 
  if ( TestCase ) exit(0);
383
 
#endif
384
 
  alarm(0);
385
 
#ifdef DEBUG
386
 
  writePidFile(getpid());
387
 
#else
388
 
#ifdef EMBED
389
 
  s=vfork();
390
 
#else
391
 
  s=fork();
392
 
#endif
393
 
  if ( s )
394
 
    {
395
 
      writePidFile(s);
396
 
      exit(0); /* got into bound state. */
397
 
    }
398
 
  setsid();
399
 
  if ( (i=open("/dev/null",O_RDWR,0)) >= 0 )
400
 
    {
401
 
      (void)dup2(i,STDIN_FILENO);
402
 
      (void)dup2(i,STDOUT_FILENO);
403
 
      (void)dup2(i,STDERR_FILENO);
404
 
      if ( i > 2 ) (void)close(i);
405
 
    }
406
 
#endif
407
 
  chdir("/");
408
 
  do currState=(void *(*)())currState(); while ( currState );
409
 
  deletePidFile();
410
 
  exit(1);
411
 
}