File: super.h

package info (click to toggle)
super 3.11.6-1
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 660 kB
  • ctags: 592
  • sloc: ansic: 7,338; sh: 183; makefile: 175
file content (551 lines) | stat: -rw-r--r-- 19,890 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
/* The code should compile with either ANSI C or K&R compilers. */

/*
 *      Copyright (c) 1995, 1996 by William Deich.
 *      Written by William Deich.  Not derived from licensed software.

 *    You may distribute under the terms of either the GNU General Public
 *    License or the Artistic License, as specified in the README file.
 */

/* Use __P() to have prototypes in STD C code, and not use
 * prototypes in K&R C: declare functions as:
 *	func_type  funcname __P((arglist));
 */

/* ==================================================================== */

#include "localsys.h"
#include "hsearch.h"
#include "version.h"

/* ==================================================================== */

#ifndef __STDC__
    extern char *malloc();
    extern char *realloc();
#endif

#ifndef HAVE_ALNUM
#define alnum(c) (isalpha(c) || isdigit(c))
#endif

#define SEP	" \t\v\n"		/* How to split fields on input lines */
#define QM	"\"'"			/* Quotemarks in fields */
#define CM	"#"			/* Comments in input file */
#define SAFE_IFS "IFS= \t\n"
#define OPTION_SEP '='			/* option separator */
#define CONDITION_SEP '~'		/* condition separator */

#define CLEAR_SETTINGS NULL

/* The safe path should normally be defined/edited in config.h.  This is
 * a just-in-case-it's-missing definition.
 */
#ifndef SAFE_PATH
#define SAFE_PATH "/bin:/usr/bin:/usr/ucb"
#endif

/* The name under this program assumes it is installed.  If argv[0] isn't
 * [/.../]ONETRUENAME, we assume we're running via symlink.
 */
#ifndef ONETRUENAME
#define ONETRUENAME "super"
#endif

/* Kind of help we give */
#define HELP_BASIC	0	/* Basic help shows what you can execute */
#define HELP_FULL	1	/* Full help on each command */
#define HELP_FACTS	2	/* Just-the-facts-ma'm mode */
#define HELP_USAGE	3	/* Print usage only, no per-cmd help */

#ifndef SUPERFILE
#define SUPERFILE "/usr/local/lib/super.tab"
#endif

#ifndef PERUSER_SUPERFILE
#define PERUSER_SUPERFILE ".supertab"
#endif

#ifndef MAXFD
int getdtablesize __P(( void ));
#define MAXFD (getdtablesize()-1)
#endif

#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif

/* MAXSETENV is maximum number of variables that can be setenv'd on a
 * super control line.  This isn't the maximum that can be passed; it's
 * only the number of environment variables definitions that can be
 * made on one control line.
 */
#define MAXSETENV 40

/* Default value for the maximum length of a user-supplied environment
 * variable definition.
 */
#define MAXENVLEN 1000

/* If defined, then user patterns are allowed to match the uid as well as
 * the actual username.  We DISABLE this by default because users are
 * almost always identified by username.
 */
/* #define MATCH_DECIMAL_UID */

/* If defined, then group patterns are allowed to match the
 * gid as well as the group name, if any.  We ENABLE this by default
 * because it's not unusual for users to be put into unnamed groups
 * in the password file.
 */
#define MATCH_DECIMAL_GID

/* maximum number of tries at entering the password */
#define MAXTRY 3

/* default maxlength per arg, maxlength all args */
#define MAXLEN1ARG 1000
#define MAXLENARGS 10000

#ifdef HAVE_INNETGR
extern int innetgr();
#endif

#ifndef HAVE_MEMSET
void *memset __P(( void *s, int c, size_t n ));
#endif

/* special code to indicate we haven't specified a uid yet */
#define UID_NOTSET ((uid_t) ~0)

/* special code to indicate we haven't specified a gid yet */
#define GID_NOTSET ((gid_t) ~0)

/* special code to indicate we haven't specified supplementary groups */
#define GROUPS_NOTSET ((GETGROUPS_T) ~0)


/* Number of elements in an array */
#define NELEM(x) (sizeof(x)/(sizeof(*x)))

/* n rounded up to a multiple of m -- both should be positive */
#define ROUNDUP(n, m) ( ((n) % (m) == 0) ? (n) : ((n)/(m) + 1)*(m) )

/* STRBEG evaluates to !0 if s1 begins with substring s2 */
#define STRBEG(s1, s2) (strncmp((s1), (s2), strlen(s2)) == 0)
 
/* STRMATCH3 expects 'end' to be a pointer into s2, and evaluates to !0
 * if characters s2..(end-1) fully match s1 (that is, the next character in
 * s1 is null.
 */
#define STRMATCH3(s1, s2, end) \
	       (strncmp(s1, s2, end-s2) == 0 && s1[end-s2]=='\0')
		    

#define UNTIL(e) while(!(e))

/* ========================================================================= */

/*
 * Super's main external variables
 */
    extern char *prog;			/* this program */
    extern int debug;			/* debug level; 0=off */
    extern int check_syntax;		/* just check syntax of superfile */
    extern char *superfile;		/* The actual superfile to be opened. */
    extern int it_came_from_cmdline;	/* Set by -F/-T/-U/-G flags */

/* The following external variables control the Error() routine.
 * They are modified at various points by super(), to give detailed control
 * over the error messages that are printed.
 */
    extern int error_stderr;		/* stderr() bool */
    extern int error_syslog;		/* syslog() bool */
    extern char *error_rlog_host;	/* where rsyslog() msgs are sent */
    extern char *error_command;		/* our program name */
    extern char *error_user;		/* our caller's username */

    extern int error_line;		/* input line number of error */
    extern int error_nl;		/* number of lines this msg refers to */
    extern char *error_srcfile;		/* filename of input with error */

/*
 * For use with strqtokS -- see that routine for definitions of strqS_xxx
 */
    extern unsigned char *strqS_qm;	/* For fast access by strqtokS */
    extern unsigned char my_qm[256];
    extern unsigned char *strqS_cc;	/* For fast access by strqtokS */
    extern unsigned char my_cc[256];
 

/*
 * Extern variable and routines used to compile/match user/group/host patterns.
 */
extern char *(*pat_compile) __P(( char *));
extern int (*pat_compare) __P(( char *));
extern int need_re_anchor;
/* ========================================================================= */

/*
 * Basic structures from which we construct other, bigger entities.
 */

struct simpleList {
    char *pat;
    struct simpleList *next;
};
typedef struct simpleList SimpleList;

struct simple2List {
    char *pat;
    struct simpleList *other;
    struct simple2List *next;
};
typedef struct simple2List Simple2List;

struct timeEnt {
    short begin;	/* Start time, in minutes */
    short end;		/* End time, in minutes */
    char day;		/* day of week to match (0..6); 7 means any day */
    char invert;	/* match is to be inverted */
};
typedef struct timeEnt TimeEnt;

struct timeList {
    TimeEnt te;
    struct timeList *next;
};
typedef struct timeList TimeList;

/* Linked open files */
struct fileList {
    char *givenname;	/* filename, as given in the parent file */
    char *fullname;	/* filename, fully expanded */
    FILE *fp;
    int line;		/* current line */
    int nl;		/* number of lines in this block */
    struct fileList *prev;
};
typedef struct fileList FileList;

struct countedString {
    char *s;		/* malloc'd string */
    int n;		/* number of characters in s */
    unsigned char used;	/* !0 means this string is in use */
};
typedef struct countedString CountedString;

struct strArray {
    CountedString *str;	/* Pts to malloc'd array of CountedString's */
    int n;		/* number strings allocated */
};
typedef struct strArray StrArray;

struct ourTime {
    time_t start;	/* when program started */
    short min;		/* local time of day, in minutes */
    char day;		/* local day, with 0=sunday */
};	
typedef struct ourTime OurTime;

struct conditions {
    int user;		/* !0 -> Last match to a user pattern */
    int time;		/* !0 -> Matched a time pattern */
    int allinverted;	/* !0 -> all time patterns scanned were inverted */
};
typedef struct conditions Conditions;

/* The progList struct is for listing all Cmd::File pairs on a control line. */
struct progList {
    char *Cmd;
    char *File;
};
typedef struct progList ProgList;

/* ========================================================================= */

/* Password information */
struct passInfo {
    int required;	/* -1 means not in use */
    int timeout;	/* Time before password must be re-entered */
    int renewtime;	/* update the timestamp file with each use of cmd? */
    int perhost;	/* create timestamp files separately for each host? */
    char user[1024];	/* value of timestampuid=xxx, if entered */
};
typedef struct passInfo PassInfo;

/* Information for logging use */
struct logInfo {
    FILE *fp;			/* logfile pointer */
    char filename[1024];	/* logfile name */
    char user[1024];		/* value of loguid=xxx, if entered */
    uid_t uid;			/* UID under which we open logfile */
    pid_t pid;			/* PID of the logger; -1 means none running. */
    unsigned char newfile;	/* Bool: !0 if logfile given but not yet used */
    unsigned char newuid;	/* Bool: !0 if loguid given, but not yet used */
};
typedef struct logInfo LogInfo;

/* progMatch is for keeping track of matches in a ProgList */
struct progMatch {
    ProgList *cmd_file;
    int match;	/* index in proglist of matched command; -1 if no match */
    int evermatched;	/* 0 if no cmd in file matched pat */
    char *commandfound;	/* If match >= 0, commandfound points to actual
			 * command matched.  This can differ from
			 * proglist.Cmd[match], because that Cmd can be
			 * a pattern.
			 */
    int n;
    int nalloc;
};
typedef struct progMatch ProgMatch;

/* ========================================================================= */

/*
 * Global information from the :global lines
 */
struct globalInfo {
    char owner[32];	/* Owner of FullPath must be this person; overridden
			 * by local owner=xxx option, if present.
			 */
    char *chdir_path;	/* Change to this dir before exec'ing; null if none */
    int relative_path;	/* Allow filenames to be relative.  This is
			 * in general a stupid idea.  Don't do it!
			 */
    int group_slash;	/* Allow group names to have slashes.  If you
			 * allow this, you make it harder to catch certain
			 * command-line typos.  Don't do it!
			 */
    int maxenvlen;	/* max length of envvar (all of "name=value") */
    char **env;		/* null-terminated list of vars from env=var[,...] */

    int nice_incr;	/* value of the nice=nnn increment value */

    int mask;		/* umask setting */

    long maxlen1arg;	/* max len of any single arg */
    long maxlenargs;	/* max len of all args, combined */

    PassInfo passinfo;	/* password information */

    Simple2List userbefore;	/* list of u/g/h pats before per-cmd pats */
    Simple2List userafter;	/* list of u/g/h pats after per-cmd pats */
    SimpleList b_a_text;	/* list of original text for above */
    int user_clear;		/* clear userbefore list if new val seen */

    TimeList timebefore;	/* A list of the actual time ranges used */
    TimeList timeafter;		/* A list of the actual time ranges used */
    int time_clear;		/* clear timebefore list if new val seen */

    int use_after;		/* !set to !0 when we see <> */

    LogInfo log;		/* Information for logging to file */

    char mailcmd[500];		/* Information for logging via mail */
    int mail_success;		/* bool: mail on success? (-1 = unknown) */
    int gethostbyname;		/* bool: use gethostbyname()? */

    GETGROUPS_T groups[NGROUPS_MAX];	/* groups from [add]groups=xxx,... */
    int ngroups;		/* number of supplementary groups */
    int groups_added;		/* bool: groups were addgroups=, not groups= */
};
typedef struct globalInfo GlobalInfo;

/*
 * Information describing the caller
 */
struct userInfo {
    struct passwd caller;		/* who's invoking program */
    char hostname[MAXHOSTNAMELEN];	/* whence came the user */
    char lc_hostname[MAXHOSTNAMELEN];	/* hostname in lower case */
    int orig_mask;			/* umask setting at startup */

    uid_t orig_uid;			/* uid at prog start, from getuid() */
    gid_t orig_gid;			/* gid at prog start, from getgid() */
    uid_t new_uid;			/* new uid, from uid=xxx or u+g=xxx */
    gid_t new_gid;			/* new gid, from gid=xxx or u+g=xxx */

    OurTime ourtime;			/* when we started, etc */

    char encr[20];			/* encrypted password */
    char salt[4];			/* salt from password */
};
typedef struct userInfo UserInfo;

/*
 * Per-entry (in the super.tab file) information.  This gets filled in
 * at various points, as the program learns more.
 */
struct localInfo {
    ProgMatch progs;	/* Records prog::file sets, and is updated w/ matches */

    char *info;		/* value of info=xxx option */
    char *die;		/* Gets msg from die=msg ; null if none */
    char *print;	/* Gets msg from print=msg ; null if none */
    char *chdir_path;	/* Change to this dir before exec'ing; null if none */

    char user[32];	/* value of uid=xxx option */
    char group[32];	/* value of gid=xxx option */
    char u_g[32];	/* value of u+g=xxx option */
    char owner[32];	/* value of owner=xxx option */
    uid_t file_uid;	/* uid of the matched FullPath */
    gid_t file_gid;	/* gid of the matched FullPath */
    GETGROUPS_T groups[NGROUPS_MAX];	/* groups from [add]groups=xxx,... */
    int ngroups;	/* number of supplementary groups */
    int groups_added;	/* bool: groups were addgroups=, not groups= */
    int maxenvlen;	/* max length of envvar (all of "name=value") */
    char **env;		/* null-terminated list of vars from env=var[,...] */
    char *setenv[MAXSETENV+1];	/* values of setenv=var[,...] option */
    char *fdlist;	/* value of fd=nnn[,...] option */
    int mask;		/* value of umask=xxx option */
    int nice_incr;	/* value of the nice=nnn increment value */
    Simple2List userpats;	/* list of PermittedUser patterns */
    SimpleList origtext;	/* list of PermittedUser patterns */
    TimeList time;	/* A list of the actual time ranges used */
    int usr_args[2];	/* number of user-entered args allowed */
    long maxlen1arg;	/* max len of any single arg */
    long maxlenargs;	/* max len of all args, combined */
    StrArray argpats;	/* argNNN=xxx arguments */

    LogInfo log;	/* Information for logging to file */

    char mailcmd[500];	/* Information for logging via mail */
    int mail_success;	/* bool: mail on successful tries? (-1 = unknown) */

    int *fd;		/* descriptors from fdlist string */
    PassInfo passinfo;	/* password requirements on this command */
};
typedef struct localInfo LocalInfo;

/* ========================================================================= */

extern FileList *currfile;		/* list of currently-open files */

extern GlobalInfo globalinfo;		/* :global info */

extern UserInfo userinfo;		/* User's info */

extern LocalInfo localinfo;		/* per-cmd info */

extern Conditions matches;		/* To keep track of what matched */

/* ========================================================================= */
void	add_builtin_variables __P(( void ));
#ifdef HAVE_SYSINFO
void	add_sysinfo_variables __P(( void ));
#endif
#ifdef HAVE_UNAME
void	add_uname_variables __P(( void ));
#endif
int	add_variable __P(( char *varname, char *vardefn ));
void	anchor __P(( char *in, char *out ));
char*	approve __P((char *usrcmd, int givehelp, int verbose));
int	blkfree __P((char **));
char ** blkdup __P((char **blk));
int	build_cmd_file __P((char *, int , char *, char **));
char**	buttonup __P((char *));
int	check_arglistlen __P(( char **argv ));
int	check_owner __P(( void ));
int	check_pass __P(( char *cmd ));
int	checkenv __P(( char *name,  char *value,  char *pat ));
char*	clean_buf __P(( char *buf, char *outbuf ));
void	close_writer __P(( void ));
int	colon_define __P(( char *command ));
int	colon_global __P(( char *command ));
int	colon_include __P(( char *command, int allow_missing ));
int	colon_if __P(( char *command, int *colonif_succeeded ));
int	conditions_and_options __P((char *cond_or_opt_wd));
char*	dayname __P(( int daynum ));
int	daynum __P(( int unixtime ));
void	debug_print __P((char *path, char **arglist, char **envp, int n_bltin));
void	debug_hello __P((void));
int	do_options __P((int argc, char **argv, int *help, int *vers,
					int *verbose, int *printvars));
char*	do_variables __P(( char *str));
void	print_variable __P(( int indx, char *key, char *data ));
char*	ends __P(( char *s1, char *s2 ));
#ifdef HAVE_STDARG_H
int	Error __P(( int show_perror, int die, char * fmt, ... ));
#else
int	Error();
#endif
FileList* file_open __P(( FileList *list, char *name, int allow_missing ));
FileList* file_close __P(( FileList *list ));
char*	fillbuffer __P(( FILE *fp, int *indentok, int *nl ));
int	findgid __P(( int allowbrackets, char *grouplabel ));
int	findgroup __P(( char *grouplabel ));
int	fixup_fullpath __P((int , char *, char *, char *, int ));
void	free_SimpleList __P(( SimpleList *));
void	free_Simple2List __P(( Simple2List *));
void	free_TimeList __P(( TimeList *));
int	get_canonical_hostname __P((char *buf, int len));
int	get_encrypted_pw __P(( void ));
int	get_owner __P((char *path, uid_t *uid, gid_t *gid));
int	get_password __P(( char *cmd, char *user,  char *salt,  char *encr ));
char*	Getenv __P(( char *s ));
int	Getgroups __P((int, GETGROUPS_T *));
int	getlogdir __P((char *user, char *buf));
struct passwd *
	getpwentry __P((int allow_brackets, char *username));
int	global_arg __P((char *word));
int	globbraces __P(( char *s, int wrap_in_braces, char ***globlist ));
int	handle_option __P((char *word, char *s, int isglobal));
int	ingroup __P(( char * user, gid_t gid, char * gp_pat ));
void	init_nice_incr __P((int is_global));
void	init_strqtokS __P(( void ));
void	init_umask __P((int is_global));
void	init_globalinfo __P( (void) );
void	init_localinfo __P( (void) );
int	init_userinfo __P( (void) );
int	InsertCondition __P(( char *, char *, int ));
int	InsertTimeList __P(( char *, char **, TimeList *, char *, int ));
int	InsertUserList __P((char *, char **, Simple2List *, SimpleList *, int));
void	logmsg __P(( char * cmd, char ** args ));
int	makedir __P(( char *directories ));
char*	makedirname __P(( char *prefix, char *hostname, char *path ));
int	match_pattern __P((int match, int glob, char *str, char *pattern));
void	match_ugh_user __P((Simple2List *sl, int isglobal));
void	matchtime __P(( OurTime *our, TimeList *tl ));
char**	newargs __P((char *path_plus, char **argv, int *n_builtin));
FILE*	open_writer __P(( char *user, char *filename, pid_t *pid_p ));
void	opensuperlog __P(( void ));
int	option_clear_settings __P((char *word, char *s, int isglobal));
int	option_global_reset_settings __P((void));
int	option_local_clear_settings __P((void));
int	parseline __P((int givehelp, int checksyntax, char *buf, char *usrcmd));
void	printhelp __P(( int verbose ));
void	printhelp_hello __P(( int verbose, char *usrcmd ));
int	process_colon_cmds __P(( char *command, int *colonif_succeeded ));
int	process_logfile_opt __P(( void ));
int	rcl_nice_incr __P((void));
int	rcl_umask __P((void));
void	re_anchor __P(( char *in, char *out));
char*	s_re_comp __P(( char *));
int	s_re_exec __P(( char *));
void	readtime_init __P(( void ));
int	readtimerange __P(( char *str, short *t1, short *t2, char *d ));
int	readtime __P(( char *str, short *t1, char *d ));
int	set_chdir __P((void));
int	set_nice_incr __P((void));
int	set_u_g __P(( void ));
void	set_umask __P((void));
int	Setgroups __P((int, GETGROUPS_T *));
int	shell_compare __P(( char *));
char*	shell_compile __P(( char *));
void	store_nice_incr __P((int nice_incr, int is_global));
void	store_umask __P((int mask, int is_global));
char*	str_val __P(( char *left, int sep, char *str ));
int	StrEltCpy __P(( StrArray *a, int ielt, char *str));
char*	StrEltGetPtr __P(( StrArray *a, int ielt ));
void	StrEltsUnused __P(( StrArray *a ));
void	StrInit __P(( StrArray *a ));
int	stringcopy __P(( char *to, char *from, int n));
int	StrLastInUse __P(( StrArray *a ));
int	StrNalloc __P(( StrArray *a, int nelt));
int	StrNelts __P(( StrArray *a ));
void	strtolower __P(( char *string ));
char*	strqtokS __P(( char *, char *, char *, char *, unsigned int ));
int	user_supertab __P(( char *command ));