+++ /dev/null
-/*
- Copyright (c) 1995-1998 by Cisco systems, Inc.
-
- Permission to use, copy, modify, and distribute this software for
- any purpose and without fee is hereby granted, provided that this
- copyright and permission notice appear on all copies of the
- software and supporting documentation, the name of Cisco Systems,
- Inc. not be used in advertising or publicity pertaining to
- distribution of the program without specific prior permission, and
- notice be given in supporting documentation that modification,
- copying and distribution is by permission of Cisco Systems, Inc.
-
- Cisco Systems, Inc. makes no representations about the suitability
- of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
- IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
-#include "tac_plus.h"
-#include <stdio.h>
-#include <errno.h>
-#include "regexp.h"
-
-/*
- <config> := <decl>*
-
- <decl> := <top_level_decl> | <user_decl>
-
- <top_level_decl> := <authen_default> |
- accounting file = <string>
- default authorization = permit |
- key = <string>
-
- <authen_default> := default authentication = file <filename>
-#if defined(DB)
- | db <string> )
-#endif
-
-<permission> := permit | deny
-
- <filename> := <string>
-
- <password> := <string>
-
- <user_decl> := user = <string> {
- [ default service = [ permit | deny ] ]
- <user_attr>*
- <svc>*
- }
-
- <password_spec> := file <filename> |
- skey |
- cleartext <password> |
- des <password> |
-
-#ifdef USE_PAM
- pam <pam_service> |
-#endif
-#if defined(DB)
- db <string>
-#endif
- nopassword
-
- <user_attr> := name = <string> |
- login = <password_spec> |
- member = <string> |
- expires = <string> |
- arap = cleartext <string> |
- chap = cleartext <string> |
-#ifdef MSCHAP
- ms-chap = cleartext <string> |
-#endif
- pap = cleartext <string> |
- pap = des <string> |
-#ifdef USE_PAM
- pap = pam <pam_service> |
-#endif
- opap = cleartext <string> |
- global = cleartext <string> |
- msg = <string>
- before authorization = <string> |
- after authorization = <string>
-
- <svc> := <svc_auth> | <cmd_auth>
-
- <cmd_auth> := cmd = <string> {
- <cmd-match>*
- }
-
- <cmd-match> := <permission> <string>
-
- <svc_auth> := service = ( exec | arap | slip | ppp protocol = <string> {
- [ default attribute = permit ]
- <attr_value_pair>*
- }
-
- <attr_value_pair> := [ optional ] <string> = <string>
-
-*/
-
-static char sym_buf[MAX_INPUT_LINE_LEN]; /* parse buffer */
-static int sym_pos=0; /* current place in sym_buf */
-static int sym_ch; /* current parse character */
-static int sym_code; /* parser output */
-static int sym_line = 1; /* current line number for parsing */
-static FILE *cf = NULL; /* config file pointer */
-static int sym_error = 0; /* a parsing error has occurred */
-static int no_user_dflt = 0; /* default if user doesn't exist */
-static char *authen_default = NULL; /* top level authentication default */
-static int authen_default_method = 0; /*For method check */
-static char *nopasswd_str = "nopassword";
-
-/* A host definition structure. Currently unused, but when we start
- configuring host-specific information e.g. per-host keys, this is
- where it should be kept.
-
- The first 2 fields (name and hash) are used by the hash table
- routines to hash this structure into a table. Do not (re)move them */
-
-struct host {
- char *name; /* host name */
- void *hash; /* hash table next pointer */
- int line; /* line number defined on */
- char *key; /* host spesific key */
- char *type; /* host type */
-};
-
-/* A user or group definition
-
- The first 2 fields (name and hash) are used by the hash table
- routines to hash this structure into a table. Move them at your
- peril */
-
-struct user {
- char *name; /* username */
- void *hash; /* hash table next pointer */
- int line; /* line number defined on */
- long flags; /* flags field */
-
-#define FLAG_ISUSER 1 /* this structure represents a user */
-#define FLAG_ISGROUP 2 /* this structure represents a group */
-#define FLAG_SEEN 4 /* for circular definition detection */
-
- char *full_name; /* users full name */
- char *login; /* Login password */
- int nopasswd; /* user requires no password */
- char *global; /* password to use if none set */
- char *member; /* group we are a member of */
- char *expires; /* expiration date */
- char *arap; /* our arap secret */
- char *pap; /* our pap secret */
- char *opap; /* our outbound pap secret */
- char *chap; /* our chap secret */
-#ifdef MSCHAP
- char *mschap; /* our mschap secret */
-#endif /* MSCHAP */
- char *msg; /* a message for this user */
- char *before_author; /* command to run before authorization */
- char *after_author; /* command to run after authorization */
- int svc_dflt; /* default authorization behaviour for svc or
- * cmd */
- NODE *svcs; /* pointer to svc nodes */
-#ifdef MAXSESS
- int maxsess; /* Max sessions/user */
-#endif /* MAXSESS */
- char *time; /* Timestamp */
-};
-
-typedef struct host HOST;
-typedef struct user USER;
-
-/* Only the first 2 fields (name and hash) are used by the hash table
- routines to hashh structures into a table.
-*/
-
-union hash {
- struct user u;
- struct host h;
-};
-
-typedef union hash HASH;
-
-void *grouptable[HASH_TAB_SIZE];/* Table of group declarations */
-void *usertable[HASH_TAB_SIZE]; /* Table of user declarations */
-void *hosttable[HASH_TAB_SIZE]; /* Table of host declarations */
-
-
-static void
- sym_get();
-
-
-#ifdef __STDC__
-#include <stdarg.h> /* ANSI C, variable length args */
-static void
-parse_error(char *fmt,...)
-#else
-#include <varargs.h> /* has 'vararg' definitions */
-/* VARARGS2 */
-static void
-parse_error(fmt, va_alist)
-char *fmt;
-
-va_dcl /* no terminating semi-colon */
-#endif
-{
- char msg[256]; /* temporary string */
- va_list ap;
-
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- vsprintf(msg, fmt, ap);
- va_end(ap);
-
- report(LOG_ERR, "%s", msg);
- fprintf(stderr, "Error: %s\n", msg);
- tac_exit(1);
-}
-
-char *
-cfg_nodestring(type)
- int type;
-{
- switch (type) {
- default:
- return ("unknown node type");
- case N_arg:
- return ("N_arg");
- case N_optarg:
- return ("N_optarg");
- case N_svc:
- return ("N_svc");
- case N_svc_exec:
- return ("N_svc_exec");
- case N_svc_slip:
- return ("N_svc_slip");
- case N_svc_ppp:
- return ("N_svc_ppp");
- case N_svc_arap:
- return ("N_svc_arap");
- case N_svc_cmd:
- return ("N_svc_cmd");
- case N_permit:
- return ("N_permit");
- case N_deny:
- return ("N_deny");
- }
-}
-
-static void
-free_attrs(node)
-NODE *node;
-{
- NODE *next;
-
- while (node) {
- switch (node->type) {
- case N_optarg:
- case N_arg:
- if (debug & DEBUG_CLEAN_FLAG)
- report(LOG_DEBUG, "free_cmd_match %s %s",
- cfg_nodestring(node->type),
- node->value);
- break;
- default:
- report(LOG_ERR, "Illegal node type %s for free_attrs",
- cfg_nodestring(node->type));
- return;
- }
-
- free(node->value);
- next = node->next;
- free(node);
- node = next;
- }
-}
-
-static void
-free_cmd_matches(node)
-NODE *node;
-{
- NODE *next;
-
- while (node) {
- if (debug & DEBUG_CLEAN_FLAG)
- report(LOG_DEBUG, "free_cmd_match %s %s",
- cfg_nodestring(node->type),
- node->value);
-
- free(node->value); /* text */
- free(node->value1); /* regexp compiled text */
- next = node->next;
- free(node);
- node = next;
- }
-}
-
-static void
-free_svcs(node)
-NODE *node;
-{
- NODE *next;
-
- while (node) {
-
- switch (node->type) {
- case N_svc_cmd:
- if (debug & DEBUG_CLEAN_FLAG)
- report(LOG_DEBUG, "free %s %s",
- cfg_nodestring(node->type), node->value);
- free(node->value); /* cmd name */
- free_cmd_matches(node->value1);
- next = node->next;
- free(node);
- node = next;
- continue;
-
- case N_svc:
- case N_svc_ppp:
- free(node->value1);
- /* FALL-THROUGH */
- case N_svc_exec:
- case N_svc_arap:
- case N_svc_slip:
- if (debug & DEBUG_CLEAN_FLAG)
- report(LOG_DEBUG, "free %s", cfg_nodestring(node->type));
- free_attrs(node->value);
- next = node->next;
- free(node);
- node = next;
- continue;
-
- default:
- report(LOG_ERR, "Illegal node type %d for free_svcs", node->type);
- return;
- }
- }
-}
-
-static void
-free_userstruct(user)
-USER *user;
-{
- if (debug & DEBUG_CLEAN_FLAG)
- report(LOG_DEBUG, "free %s %s",
- (user->flags & FLAG_ISUSER) ? "user" : "group",
- user->name);
-
- if (user->name)
- free(user->name);
- if (user->full_name)
- free(user->full_name);
- if (user->login)
- free(user->login);
- if (user->member)
- free(user->member);
- if (user->expires)
- free(user->expires);
- if (user->time)
- free(user->time);
- if (user->arap)
- free(user->arap);
- if (user->chap)
- free(user->chap);
-#ifdef MSCHAP
- if (user->mschap)
- free(user->mschap);
-#endif /* MSCHAP */
- if (user->pap)
- free(user->pap);
- if (user->opap)
- free(user->opap);
- if (user->global)
- free(user->global);
- if (user->msg)
- free(user->msg);
- if (user->before_author)
- free(user->before_author);
- if (user->after_author)
- free(user->after_author);
- free_svcs(user->svcs);
-}
-
-static void
-free_hoststruct(host)
-HOST *host;
-{
- if (debug & DEBUG_CLEAN_FLAG)
- report(LOG_DEBUG, "free %s",
- host->name);
-
- if (host->name)
- free(host->name);
-
- if (host->key)
- free(host->key);
-
- if (host->type)
- free(host->type);
-}
-
-/*
- * Exported routines
- */
-
-/* Free all allocated structures preparatory to re-reading the config file */
-void
-cfg_clean_config()
-{
- int i;
- USER *entry, *next;
- HOST *host_entry,*hn;
-
- if (authen_default) {
- free(authen_default);
- authen_default = NULL;
- }
-
- if (authen_default_method) {
- authen_default_method = 0;
- }
-
- if (session.key) {
- free(session.key);
- session.key = NULL;
- }
-
- if (session.acctfile) {
- free(session.acctfile);
- session.acctfile = NULL;
- }
-
- if (session.db_acct) {
- free(session.db_acct);
- session.db_acct = NULL;
- }
-
- /* clean the hosttable */
- for (i = 0; i < HASH_TAB_SIZE; i++) {
- host_entry = (HOST *) hosttable[i];
- while (host_entry) {
- hn = host_entry->hash;
- free_hoststruct(host_entry);
- free(host_entry);
- host_entry = hn;
- }
- hosttable[i] = NULL;
- }
-
- /* the grouptable */
- for (i = 0; i < HASH_TAB_SIZE; i++) {
- entry = (USER *) grouptable[i];
- while (entry) {
- next = entry->hash;
- free_userstruct(entry);
- free(entry);
- entry = next;
- }
- grouptable[i] = NULL;
- }
-
- /* the usertable */
- for (i = 0; i < HASH_TAB_SIZE; i++) {
- entry = (USER *) usertable[i];
- while (entry) {
- next = entry->hash;
- free_userstruct(entry);
- free(entry);
- entry = next;
- }
- usertable[i] = NULL;
- }
-}
-
-static int
-parse_permission()
-{
- int symbol = sym_code;
-
- if (sym_code != S_permit && sym_code != S_deny) {
- parse_error("expecting permit or deny but found '%s' on line %d",
- sym_buf, sym_line);
- return (0);
- }
- sym_get();
-
- return (symbol);
-}
-
-static int
-parse(symbol)
-int symbol;
-
-{
- if (sym_code != symbol) {
- parse_error("expecting '%s' but found '%s' on line %d",
- (symbol == S_string ? "string" : codestring(symbol)),
- sym_buf, sym_line);
- return (1);
- }
- sym_get();
- return (0);
-}
-
-static int
-parse_opt_svc_default()
-{
- if (sym_code != S_default) {
- return (0);
- }
-
- parse(S_default);
- parse(S_svc);
- parse(S_separator);
- if (sym_code == S_permit) {
- parse(S_permit);
- return (S_permit);
- }
- parse(S_deny);
- return (S_deny);
-}
-
-static int
-parse_opt_attr_default()
-{
- if (sym_code != S_default)
- return (S_deny);
-
- parse(S_default);
- parse(S_attr);
- parse(S_separator);
- parse(S_permit);
- return (S_permit);
-}
-
-static int parse_user();
-static int parse_host();
-
-static void
- rch();
-
-/*
- Parse lines in the config file, creating data structures
- Return 1 on error, otherwise 0 */
-
-static int
-parse_decls()
-{
- no_user_dflt = 0; /* default if user doesn't exist */
-
- sym_code = 0;
- rch();
-
- bzero(grouptable, sizeof(grouptable));
- bzero(usertable, sizeof(usertable));
- bzero(hosttable, sizeof(hosttable));
-
- sym_get();
-
- /* Top level of parser */
- while (1) {
-
- switch (sym_code) {
- case S_eof:
- return (0);
-
- case S_accounting:
- sym_get();
- parse(S_file);
- parse(S_separator);
- if (session.acctfile)
- free(session.acctfile);
- session.acctfile = tac_strdup(sym_buf);
- sym_get();
- continue;
-
-#ifdef DB
- case S_db_accounting:
- sym_get();
- parse(S_separator);
- if (session.db_acct)
- free(session.db_acct);
- session.db_acct = tac_strdup(sym_buf);
- sym_get();
- continue;
-#endif
-
- case S_default:
- sym_get();
- switch (sym_code) {
- default:
- parse_error(
- "Expecting default authorization/authentication on lines %d",
- sym_line);
- return (1);
-
- case S_authentication:
- if (authen_default) {
- parse_error(
- "Multiply defined authentication default on line %d",
- sym_line);
- return (1);
- }
- parse(S_authentication);
- parse(S_separator);
-
- switch(sym_code) {
-
- case S_file:
-#ifdef DB
- case S_db:
-#endif
-#ifdef USE_LDAP
- case S_ldap;
-#endif
-#ifdef USE_PAM
- case S_pam:
-#endif
- authen_default_method = sym_code;
- break;
-
- default:
- parse_error("expecting default_method keyword after 'default authentication = ' on line %d",sym_line);
- return (1);
- }
- sym_get();
-
- authen_default = tac_strdup(sym_buf);
- sym_get();
- continue;
-
- case S_authorization:
- parse(S_authorization);
- parse(S_separator);
- parse(S_permit);
- no_user_dflt = S_permit;
- report(LOG_INFO,
- "default authorization = permit is now deprecated. Please use user = DEFAULT instead");
- continue;
- }
-
- case S_key:
- /* Process a key declaration. */
- sym_get();
- parse(S_separator);
- if (session.key) {
- parse_error("multiply defined key on lines %d and %d",
- session.keyline, sym_line);
- return (1);
- }
- session.key = tac_strdup(sym_buf);
- session.keyline = sym_line;
- sym_get();
- continue;
-
- case S_host:
- parse_host();
- continue;
-
- case S_user:
- case S_group:
- parse_user();
- continue;
-
- /* case S_host: parse_host(); continue; */
-
- default:
- parse_error("Unrecognised token %s on line %d", sym_buf, sym_line);
- return (1);
- }
- }
-}
-
-static NODE *parse_svcs();
-
-/* Assign a value to a field. Issue an error message and return 1 if
- it's already been assigned. This is a macro because I was sick of
- repeating the same code fragment over and over */
-
-#define ASSIGN(field) \
-sym_get(); parse(S_separator); if (field) { \
- parse_error("Duplicate value for %s %s and %s on line %d", \
- codestring(sym_code), field, sym_buf, sym_line); \
- tac_exit(1); \
- } \
- field = tac_strdup(sym_buf);
-
-static int
-parse_host()
-{
- HOST *h;
- HOST *host = (HOST *) tac_malloc(sizeof(HOST));
- int save_sym;
- char buf[MAX_INPUT_LINE_LEN];
-
- bzero(host, sizeof(HOST));
-
- sym_get();
- parse(S_separator);
- host->name = tac_strdup(sym_buf);
- host->line = sym_line;
-
- h = hash_add_entry(hosttable, (void *) host);
-
- if (h) {
- parse_error("multiply defined %s on lines %d and %d",
- host->name, h->line, sym_line);
- return (1);
- }
-
- sym_get();
- parse(S_openbra);
-
- while (1) {
- switch (sym_code) {
- case S_eof:
- return (0);
- case S_key:
- ASSIGN(host->key);
- sym_get();
- continue;
- case S_type:
- ASSIGN(host->type);
- sym_get();
- continue;
-
- case S_closebra:
- parse(S_closebra);
- return (0);
-
- default:
- parse_error("Unrecognised keyword %s for host %s on line %d",
- sym_buf, host->name,sym_line);
-
- return (0);
- }
- } /* while */
-} /* finish parse_host */
-
-
-static int
-parse_user()
-{
- USER *n;
- int isuser;
- USER *user = (USER *) tac_malloc(sizeof(USER));
- int save_sym;
- char **fieldp;
- char buf[MAX_INPUT_LINE_LEN];
-
- bzero(user, sizeof(USER));
-
- isuser = (sym_code == S_user);
-
- sym_get();
- parse(S_separator);
- user->name = tac_strdup(sym_buf);
- user->line = sym_line;
-
- if (isuser) {
- user->flags |= FLAG_ISUSER;
- n = hash_add_entry(usertable, (void *) user);
- } else {
- user->flags |= FLAG_ISGROUP;
- n = hash_add_entry(grouptable, (void *) user);
- }
-
- if (n) {
- parse_error("multiply defined %s %s on lines %d and %d",
- isuser ? "user" : "group",
- user->name, n->line, sym_line);
- return (1);
- }
- sym_get();
- parse(S_openbra);
-
- /* Is the default deny for svcs or cmds to be overridden? */
- user->svc_dflt = parse_opt_svc_default();
-
- while (1) {
- switch (sym_code) {
- case S_eof:
- return (0);
-
- case S_time:
- ASSIGN(user->time);
- sym_get();
- continue;
-
- case S_before:
- sym_get();
- parse(S_authorization);
- if (user->before_author)
- free(user->before_author);
- user->before_author = tac_strdup(sym_buf);
- sym_get();
- continue;
-
- case S_after:
- sym_get();
- parse(S_authorization);
- if (user->after_author)
- free(user->after_author);
- user->after_author = tac_strdup(sym_buf);
- sym_get();
- continue;
-
- case S_svc:
- case S_cmd:
-
- if (user->svcs) {
- /*
- * Already parsed some services/commands. Thanks to Gabor Kiss
- * who found this bug.
- */
- NODE *p;
- for (p=user->svcs; p->next; p=p->next)
- /* NULL STMT */;
- p->next = parse_svcs();
- } else {
- user->svcs = parse_svcs();
- }
- continue;
-
- case S_login:
- if (user->login) {
- parse_error("Duplicate value for %s %s and %s on line %d",
- codestring(sym_code), user->login,
- sym_buf, sym_line);
- tac_exit(1);
- }
- sym_get();
- parse(S_separator);
- switch(sym_code) {
-
- case S_skey:
- user->login = tac_strdup(sym_buf);
- break;
-
- case S_nopasswd:
- /* set to dummy string, so that we detect a duplicate
- * password definition attempt
- */
- user->login = tac_strdup(nopasswd_str);
- user->nopasswd = 1;
- break;
-
- case S_file:
- case S_cleartext:
- case S_des:
-#ifdef USE_PAM
- case S_pam:
-#endif /* USE_PAM */
-#ifdef DB
- case S_db:
-#endif /* USE DB */
- sprintf(buf, "%s ", sym_buf);
- sym_get();
- strcat(buf, sym_buf);
- user->login = tac_strdup(buf);
- break;
-
- default:
-#ifdef USE_PAM
- parse_error(
- "expecting 'file', 'cleartext', 'pam'.'nopassword', 'skey', or 'des' keyword after 'login =' on line %d",
- sym_line);
-#else
- parse_error(
- "expecting 'file', 'cleartext', 'nopassword', 'skey', or 'des' keyword after 'login =' on line %d",
- sym_line);
-#endif /* USE_PAM */
- }
- sym_get();
- continue;
-
- case S_pap:
- if (user->pap) {
- parse_error("Duplicate value for %s %s and %s on line %d",
- codestring(sym_code), user->pap,
- sym_buf, sym_line);
- tac_exit(1);
- }
- sym_get();
- parse(S_separator);
- switch(sym_code) {
-
- case S_cleartext:
- case S_des:
-#ifdef USE_PAM
- case S_pam:
-#endif /*USE_PAM */
- sprintf(buf, "%s ", sym_buf);
- sym_get();
- strcat(buf, sym_buf);
- user->pap = tac_strdup(buf);
- break;
-
- sprintf(buf, "%s ", sym_buf);
- user->pap = tac_strdup(buf);
- break;
-
- default:
-#ifdef USE_PAM
- parse_error(
- "expecting 'cleartext', 'pam', or 'des' keyword after 'pap =' on line %d",
- sym_line);
-#else
- parse_error(
- "expecting 'cleartext', or 'des' keyword after 'pap =' on line %d",
- sym_line);
-#endif /*USE_PAM */
- }
- sym_get();
- continue;
-
- case S_name:
- ASSIGN(user->full_name);
- sym_get();
- continue;
-
- case S_member:
- ASSIGN(user->member);
- sym_get();
- continue;
-
-
- case S_expires:
- ASSIGN(user->expires);
- sym_get();
- continue;
-
- case S_message:
- ASSIGN(user->msg);
- sym_get();
- continue;
-
- case S_arap:
- case S_chap:
-#ifdef MSCHAP
- case S_mschap:
-#endif /* MSCHAP */
- case S_opap:
- case S_global:
- save_sym = sym_code;
- sym_get();
- parse(S_separator);
- sprintf(buf, "%s ", sym_buf);
- parse(S_cleartext);
- strcat(buf, sym_buf);
-
- if (save_sym == S_arap)
- fieldp = &user->arap;
- if (save_sym == S_chap)
- fieldp = &user->chap;
-#ifdef MSCHAP
- if (save_sym == S_mschap)
- fieldp = &user->mschap;
-#endif /* MSCHAP */
- if (save_sym == S_pap)
- fieldp = &user->pap;
- if (save_sym == S_opap)
- fieldp = &user->opap;
- if (save_sym == S_global)
- fieldp = &user->global;
-
- if (*fieldp) {
- parse_error("Duplicate value for %s %s and %s on line %d",
- codestring(save_sym), *fieldp, sym_buf, sym_line);
- tac_exit(1);
- }
- *fieldp = tac_strdup(buf);
- sym_get();
- continue;
-
- case S_closebra:
- parse(S_closebra);
- return (0);
-
-#ifdef MAXSESS
- case S_maxsess:
- sym_get();
- parse(S_separator);
- if (sscanf(sym_buf, "%d", &user->maxsess) != 1) {
- parse_error("expecting integer, found '%s' on line %d",
- sym_buf, sym_line);
- }
- sym_get();
- continue;
-#endif /* MAXSESS */
-
- default:
- if (STREQ(sym_buf, "password")) {
- fprintf(stderr,
- "\npassword = <string> is obsolete. Use login = des <string>\n");
- }
- parse_error("Unrecognised keyword %s for user on line %d",
- sym_buf, sym_line);
-
- return (0);
- }
- }
-}
-
-static NODE *parse_attrs();
-static NODE *parse_cmd_matches();
-
-static NODE *
-parse_svcs()
-{
- NODE *result;
-
- switch (sym_code) {
- default:
- return (NULL);
- case S_svc:
- case S_cmd:
- break;
- }
-
- result = (NODE *) tac_malloc(sizeof(NODE));
-
- bzero(result, sizeof(NODE));
- result->line = sym_line;
-
- /* cmd declaration */
- if (sym_code == S_cmd) {
- parse(S_cmd);
- parse(S_separator);
- result->value = tac_strdup(sym_buf);
-
- sym_get();
- parse(S_openbra);
-
- result->value1 = parse_cmd_matches();
- result->type = N_svc_cmd;
-
- parse(S_closebra);
- result->next = parse_svcs();
- return (result);
- }
-
- /* svc declaration */
- parse(S_svc);
- parse(S_separator);
- switch (sym_code) {
- default:
- parse_error("expecting service type but found %s on line %d",
- sym_buf, sym_line);
- return (NULL);
-
- case S_string:
- result->type = N_svc;
- /* should perhaps check that this is an allowable service name */
- result->value1 = tac_strdup(sym_buf);
- break;
- case S_exec:
- result->type = N_svc_exec;
- break;
- case S_arap:
- result->type = N_svc_arap;
- break;
- case S_slip:
- result->type = N_svc_slip;
- break;
- case S_ppp:
- result->type = N_svc_ppp;
- parse(S_ppp);
- parse(S_protocol);
- parse(S_separator);
- /* Should perhaps check that this is a known PPP protocol name */
- result->value1 = tac_strdup(sym_buf);
- break;
- }
- sym_get();
- parse(S_openbra);
- result->dflt = parse_opt_attr_default();
- result->value = parse_attrs();
- parse(S_closebra);
- result->next = parse_svcs();
- return (result);
-}
-
-/* <cmd-match> := <permission> <string> */
-
-static NODE *
-parse_cmd_matches()
-{
- NODE *result;
-
- if (sym_code != S_permit && sym_code != S_deny) {
- return (NULL);
- }
- result = (NODE *) tac_malloc(sizeof(NODE));
-
- bzero(result, sizeof(NODE));
- result->line = sym_line;
-
- result->type = (parse_permission() == S_permit) ? N_permit : N_deny;
- result->value = tac_strdup(sym_buf);
-
- result->value1 = (void *) regcomp(result->value);
- if (!result->value1) {
- report(LOG_ERR, "in regular expression %s on line %d",
- sym_buf, sym_line);
- tac_exit(1);
- }
- sym_get();
-
- result->next = parse_cmd_matches();
-
- return (result);
-}
-
-static NODE *
-parse_attrs()
-{
- NODE *result;
- char buf[MAX_INPUT_LINE_LEN];
- int optional = 0;
-
- if (sym_code == S_closebra) {
- return (NULL);
- }
- result = (NODE *) tac_malloc(sizeof(NODE));
-
- bzero(result, sizeof(NODE));
- result->line = sym_line;
-
- if (sym_code == S_optional) {
- optional++;
- sym_get();
- }
- result->type = optional ? N_optarg : N_arg;
-
- strcpy(buf, sym_buf);
- parse(S_string);
- strcat(buf, sym_buf);
- parse(S_separator);
- strcat(buf, sym_buf);
- parse(S_string);
-
- result->value = tac_strdup(buf);
- result->next = parse_attrs();
- return (result);
-}
-
-
-static void
- getsym();
-
-static void
-sym_get()
-{
- getsym();
-
- if (debug & DEBUG_PARSE_FLAG) {
- report(LOG_DEBUG, "line=%d sym=%s code=%d buf='%s'",
- sym_line, codestring(sym_code), sym_code, sym_buf);
- }
-}
-
-static char *
-sym_buf_add(c)
-char c;
-{
- if (sym_pos >= MAX_INPUT_LINE_LEN) {
- sym_buf[MAX_INPUT_LINE_LEN-1] = '\0';
- if (debug & DEBUG_PARSE_FLAG) {
- report(LOG_DEBUG, "line too long: line=%d sym=%s code=%d buf='%s'",
- sym_line, codestring(sym_code), sym_code, sym_buf);
- }
- return(NULL);
- }
-
- sym_buf[sym_pos++] = c;
- return(sym_buf);
-}
-
-static void
-getsym()
-{
-
-next:
- switch (sym_ch) {
-
- case EOF:
- sym_code = S_eof;
- return;
-
- case '\n':
- sym_line++;
- rch();
- goto next;
-
- case '\t':
- case ' ':
- while (sym_ch == ' ' || sym_ch == '\t')
- rch();
- goto next;
-
- case '=':
- strcpy(sym_buf, "=");
- sym_code = S_separator;
- rch();
- return;
-
- case '{':
- strcpy(sym_buf, "{");
- sym_code = S_openbra;
- rch();
- return;
-
- case '}':
- strcpy(sym_buf, "}");
- sym_code = S_closebra;
- rch();
- return;
-
- case '#':
- while ((sym_ch != '\n') && (sym_ch != EOF))
- rch();
- goto next;
-
- case '"':
- rch();
- sym_pos = 0;
- while (1) {
-
- if (sym_ch == '"') {
- break;
- }
-
- /* backslash-double-quote is supported inside strings */
- /* also allow \n */
- if (sym_ch == '\\') {
- rch();
- switch (sym_ch) {
- case 'n':
- /* preserve the slash for \n */
- if (!sym_buf_add('\\')) {
- sym_code = S_unknown;
- rch();
- return;
- }
-
- /* fall through */
- case '"':
- if (!sym_buf_add(sym_ch)) {
- sym_code = S_unknown;
- rch();
- return;
- }
- rch();
- continue;
- default:
- sym_code = S_unknown;
- rch();
- return;
- }
- }
- if (!sym_buf_add(sym_ch)) {
- sym_code = S_unknown;
- rch();
- return;
- }
- rch();
- }
- rch();
-
- if (!sym_buf_add('\0')) {
- sym_code = S_unknown;
- rch();
- return;
- }
- sym_code = S_string;
- return;
-
- default:
- sym_pos = 0;
- while (sym_ch != '\t' && sym_ch != ' ' && sym_ch != '='
- && sym_ch != '\n') {
-
- if (!sym_buf_add(sym_ch)) {
- sym_code = S_unknown;
- rch();
- return;
- }
- rch();
- }
-
- if (!sym_buf_add('\0')) {
- sym_code = S_unknown;
- rch();
- return;
- }
- sym_code = keycode(sym_buf);
- if (sym_code == S_unknown)
- sym_code = S_string;
- return;
- }
-}
-
-static void
-rch()
-{
- if (sym_error) {
- sym_ch = EOF;
- return;
- }
- sym_ch = getc(cf);
-
- if (parse_only && sym_ch != EOF)
- fprintf(stderr, "%c", sym_ch);
-}
-
-
-/* For a user or group, find the value of a field. Does not recurse. */
-VALUE
-get_value(user, field)
-USER *user;
-int field;
-{
- VALUE v;
-
- v.intval = 0;
-
- if (!user) {
- parse_error("get_value: illegal user");
- return (v);
- }
- switch (field) {
-
- case S_name:
- v.pval = user->name;
- break;
-
- case S_login:
- v.pval = user->login;
- break;
-
- case S_global:
- v.pval = user->global;
- break;
-
- case S_member:
- v.pval = user->member;
- break;
-
- case S_expires:
- v.pval = user->expires;
- break;
-
- case S_arap:
- v.pval = user->arap;
- break;
-
- case S_chap:
- v.pval = user->chap;
- break;
-
-#ifdef MSCHAP
- case S_mschap:
- v.pval = user->mschap;
- break;
-#endif /* MSCHAP */
-
- case S_pap:
- v.pval = user->pap;
- break;
-
- case S_opap:
- v.pval = user->opap;
- break;
-
- case S_message:
- v.pval = user->msg;
- break;
-
- case S_svc:
- v.pval = user->svcs;
- break;
-
- case S_before:
- v.pval = user->before_author;
- break;
-
- case S_after:
- v.pval = user->after_author;
- break;
-
- case S_svc_dflt:
- v.intval = user->svc_dflt;
- break;
-
-#ifdef MAXSESS
- case S_maxsess:
- v.intval = user->maxsess;
- break;
-#endif
-
- case S_nopasswd:
- v.intval = user->nopasswd;
- break;
-
- case S_time:
- v.pval = user->time;
- break;
-
- default:
- report(LOG_ERR, "get_value: unknown field %d", field);
- break;
- }
- return (v);
-}
-
-/* For host , find value of field. Doesn't recursive */
-VALUE
-get_hvalue(host, field)
-HOST *host;
-int field;
-{
- VALUE v;
- v.intval = 0;
- if(!host) {
- parse_error("get_hvalue: illegal host");
- return (v);
- }
- switch (field) {
- case S_name:
- v.pval = host->name;
- break;
-
- case S_key:
- v.pval = host->key;
- break;
-
- default:
- report(LOG_ERR, "get_value: unknown field %d", field);
- break;
- }
- return (v);
-}
-
-
-/* For each user, check she doesn't circularly reference a
- group. Return 1 if it does */
-static int
-circularity_check()
-{
- USER *user, *entry, *group;
- USER **users = (USER **) hash_get_entries(usertable);
- USER **groups = (USER **) hash_get_entries(grouptable);
- USER **p, **q;
-
- /* users */
- for (p = users; *p; p++) {
- user = *p;
-
- if (debug & DEBUG_PARSE_FLAG)
- report(LOG_DEBUG, "circularity_check: user=%s", user->name);
-
- /* Initialise all groups "seen" flags to zero */
- for (q = groups; *q; q++) {
- group = *q;
- group->flags &= ~FLAG_SEEN;
- }
-
- entry = user;
-
- while (entry) {
- /* check groups we are a member of */
- char *groupname = entry->member;
-
- if (debug & DEBUG_PARSE_FLAG)
- report(LOG_DEBUG, "\tmember of group %s",
- groupname ? groupname : "<none>");
-
-
- /* if not a member of any groups, go on to next user */
- if (!groupname)
- break;
-
- group = (USER *) hash_lookup(grouptable, groupname);
- if (!group) {
- report(LOG_ERR, "%s=%s, group %s does not exist",
- (entry->flags & FLAG_ISUSER) ? "user" : "group",
- entry->name, groupname);
- free(users);
- free(groups);
- return (1);
- }
- if (group->flags & FLAG_SEEN) {
- report(LOG_ERR, "recursively defined groups");
-
- /* print all seen "groups" */
- for (q = groups; *q; q++) {
- group = *q;
- if (group->flags & FLAG_SEEN)
- report(LOG_ERR, "%s", group->name);
- }
- free(users);
- free(groups);
- return (1);
- }
- group->flags |= FLAG_SEEN; /* mark group as seen */
- entry = group;
- }
- }
- free(users);
- free(groups);
- return (0);
-}
-
-
-/* Return a value for a group or user (isuser says if
- this name is a group or a user name).
-
- If no value exists, and recurse is true, also check groups we are a
- member of, recursively.
-
- Returns void * because it can return a string or a node pointer
- (should really return a union pointer).
-*/
-static VALUE
-cfg_get_value(name, isuser, attr, recurse)
-char *name;
-int isuser, attr, recurse;
-{
- USER *user, *group;
- VALUE value;
-
- value.pval = NULL;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_value: name=%s isuser=%d attr=%s rec=%d",
- name, isuser, codestring(attr), recurse);
-
- /* find the user/group entry */
-
- user = (USER *) hash_lookup(isuser ? usertable : grouptable, name);
-
- if (!user) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_value: no user/group named %s", name);
- return (value);
- }
-
- /* found the entry. Lookup value from attr=value */
- value = get_value(user, attr);
-
- if (value.pval || !recurse) {
- return (value);
- }
- /* no value. Check containing group */
- if (user->member)
- group = (USER *) hash_lookup(grouptable, user->member);
- else
- group = NULL;
-
- while (group) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_value: recurse group = %s",
- group->name);
-
- value = get_value(group, attr);
-
- if (value.pval) {
- return (value);
- }
- /* still nothing. Check containing group and so on */
-
- if (group->member)
- group = (USER *) hash_lookup(grouptable, group->member);
- else
- group = NULL;
- }
-
- /* no value for this user or her containing groups */
- value.pval = NULL;
- return (value);
-}
-
-
-/* Wrappers for cfg_get_value */
-int
-cfg_get_intvalue(name, isuser, attr, recurse)
-char *name;
-int isuser, attr, recurse;
-{
- int val = cfg_get_value(name, isuser, attr, recurse).intval;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_intvalue: returns %d", val);
- return(val);
-}
-
-char *
-cfg_get_pvalue(name, isuser, attr, recurse)
-char *name;
-int isuser, attr, recurse;
-{
- char *p = cfg_get_value(name, isuser, attr, recurse).pval;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_pvalue: returns %s",
- p ? p : "NULL");
- return(p);
-}
-
-/* For getting host values */
-static VALUE
-cfg_get_hvalue(name, attr)
-char *name;
-int attr;
-{
- HOST *host;
- VALUE value;
-
- value.pval = NULL;
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_hvalue: name=%s attr=%s ",
- name, codestring(attr));
-
- /* find the host entry in hash table */
-
- host = (HOST *) hash_lookup( hosttable, name);
-
- if (!host) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_hvalue: no host named %s", name);
- return (value);
- }
-
- /* found the entry. Lookup value from attr=value */
- value = get_hvalue(host, attr);
-
- if (value.pval) {
- return (value);
- }
- /* No any value for this host */
- value.pval = NULL;
- return (value);
-}
-
-/* Wrappers for cfg_get_hvalue */
-char *
-cfg_get_phvalue(name, attr)
-char *name;
-int attr;
-{
- char *p = cfg_get_hvalue(name, attr).pval;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_phvalue: returns %s",
- p ? p : "NULL");
- return(p);
-}
-
-/*
- Read the config file and do some basic sanity checking on
- it. Return 1 if we find any errors. */
-
-cfg_read_config(cfile)
-char *cfile;
-{
- sym_line = 1;
-
- if ((cf = fopen(cfile, "r")) == NULL) {
- report(LOG_ERR, "read_config: fopen() error for file %s %s, exiting",
- cfile, sys_errlist[errno]);
- return (1);
- }
- if (parse_decls() || sym_error) {
- fclose(cf);
- return (1);
- }
-
- if (circularity_check()) {
- fclose(cf);
- return (1);
- }
-
- fclose(cf);
- return (0);
-}
-
-/* return 1 if user exists, 0 otherwise */
-int
-cfg_user_exists(username)
-char *username;
-{
- USER *user = (USER *) hash_lookup(usertable, username);
-
- return (user != NULL);
-}
-
-/* return expiry string of user. If none, try groups she is a member
- on, and so on, recursively if recurse is non-zero */
-char *
-cfg_get_expires(username, recurse)
-char *username;
-
-{
- return (cfg_get_pvalue(username, TAC_IS_USER, S_expires, recurse));
-}
-
-/* return time string of user. If none, try groups she is a member
- on, and so on, recursively if recurse is non-zero */
-char *
-cfg_get_timestamp(username, recurse)
-char *username;
-{
- return (cfg_get_pvalue(username, TAC_IS_USER, S_time, recurse));
-}
-
-
-/* return password string of user. If none, try groups she is a member
- on, and so on, recursively if recurse is non-zero */
-char *
-cfg_get_login_secret(user, recurse)
-char *user;
-
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_login, recurse));
-}
-
-/* return value of the nopasswd field. If none, try groups she is a member
- on, and so on, recursively if recurse is non-zero */
-int
-cfg_get_user_nopasswd(user, recurse)
- char *user;
-{
- return (cfg_get_intvalue(user, TAC_IS_USER, S_nopasswd, recurse));
-}
-
-/* return user's secret. If none, try groups she is a member
- on, and so on, recursively if recurse is non-zero */
-char *
-cfg_get_arap_secret(user, recurse)
-char *user;
-
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_arap, recurse));
-}
-
-char *
-cfg_get_chap_secret(user, recurse)
-char *user;
-
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_chap, recurse));
-}
-
-#ifdef MSCHAP
-char *
-cfg_get_mschap_secret(user, recurse)
-char *user;
-
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_mschap, recurse));
-}
-#endif /* MSCHAP */
-
-char *
-cfg_get_pap_secret(user, recurse)
-char *user;
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_pap, recurse));
-}
-
-char *
-cfg_get_opap_secret(user, recurse)
-char *user;
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_opap, recurse));
-}
-
-/* return the global password for the user (or the group, etc.) */
-
-char *
-cfg_get_global_secret(user, recurse)
-char *user;
-
-{
- return (cfg_get_pvalue(user, TAC_IS_USER, S_global, recurse));
-}
-
-#ifdef USE_PAM
-/* Return a pointer to a node representing a PAM Service name */
-char *
-cfg_get_pam_service(user,recurse)
-char *user;
-
-{
- char *cfg_passwd;
- char *p;
-
-cfg_passwd = cfg_get_pap_secret(user, recurse);
-
-if (!cfg_passwd) {
- cfg_passwd = cfg_get_global_secret(user, recurse);
-}
-
-if (!cfg_passwd && !cfg_user_exists(user)) {
- cfg_passwd = cfg_get_authen_default();
- switch (cfg_get_authen_default_method()) {
- case (S_pam):
- if (debug & DEBUG_AUTHOR_FLAG)
- report(LOG_DEBUG, "Get Default PAM Service :%s",cfg_passwd);
- return(cfg_passwd);
- break;
- default:
- if (debug & DEBUG_AUTHOR_FLAG)
- report(LOG_DEBUG, "I havent find any PAM Service!!");
- return(NULL);/* Haven't any PAM Service!! */
- }
-}
-
-p=tac_find_substring("pam ", cfg_passwd);
-
-if(p) { /* We find PAM services */
- if (debug & DEBUG_AUTHOR_FLAG)
- report(LOG_DEBUG, "I get PAM sevice:%s",p);
-return (p);
-}
-
-if (debug & DEBUG_AUTHOR_FLAG)
- report(LOG_DEBUG, "No any PAM Sevice");
-
-return(NULL);
-}
-
-#endif /* For PAM */
-
-
-
-/* Return a pointer to a node representing a given service
- authorization, taking care of recursion issues correctly. Protocol
- is only read if the type is N_svc_ppp. svcname is only read if type
- is N_svc.
-*/
-
-NODE *
-cfg_get_svc_node(username, type, protocol, svcname, recurse)
-char *username;
-int type;
-char *protocol, *svcname;
-int recurse;
-{
- USER *user, *group;
- NODE *svc;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG,
- "cfg_get_svc_node: username=%s %s proto=%s svcname=%s rec=%d",
- username,
- cfg_nodestring(type),
- protocol ? protocol : "",
- svcname ? svcname : "",
- recurse);
-
- /* find the user/group entry */
- user = (USER *) hash_lookup(usertable, username);
-
- if (!user) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_svc_node: no user named %s", username);
- return (NULL);
- }
-
- /* found the user entry. Find svc node */
- for(svc = (NODE *) get_value(user, S_svc).pval; svc; svc = svc->next) {
-
- if (svc->type != type)
- continue;
-
- if (type == N_svc_ppp && !STREQ(svc->value1, protocol)) {
- continue;
- }
-
- if (type == N_svc && !STREQ(svc->value1, svcname)) {
- continue;
- }
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG,
- "cfg_get_svc_node: found %s proto=%s svcname=%s",
- cfg_nodestring(type),
- protocol ? protocol : "",
- svcname ? svcname : "");
-
- return(svc);
- }
-
- if (!recurse) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_svc_node: returns NULL");
- return (NULL);
- }
-
- /* no matching node. Check containing group */
- if (user->member)
- group = (USER *) hash_lookup(grouptable, user->member);
- else
- group = NULL;
-
- while (group) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_svc_node: recurse group = %s",
- group->name);
-
- for(svc = (NODE *) get_value(group, S_svc).pval; svc; svc = svc->next) {
-
- if (svc->type != type)
- continue;
-
- if (type == N_svc_ppp && !STREQ(svc->value1, protocol)) {
- continue;
- }
-
- if (type == N_svc && !STREQ(svc->value1, svcname)) {
- continue;
- }
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG,
- "cfg_get_svc_node: found %s proto=%s svcname=%s",
- cfg_nodestring(type),
- protocol ? protocol : "",
- svcname ? svcname : "");
-
- return(svc);
- }
-
- /* still nothing. Check containing group and so on */
-
- if (group->member)
- group = (USER *) hash_lookup(grouptable, group->member);
- else
- group = NULL;
- }
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_svc_node: returns NULL");
-
- /* no matching svc node for this user or her containing groups */
- return (NULL);
-}
-
-/* Return a pointer to the node representing a set of command regexp
- matches for a user and command, handling recursion issues correctly */
-NODE *
-cfg_get_cmd_node(name, cmdname, recurse)
-char *name, *cmdname;
-int recurse;
-
-{
- USER *user, *group;
- NODE *svc;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: name=%s cmdname=%s rec=%d",
- name, cmdname, recurse);
-
- /* find the user/group entry */
- user = (USER *) hash_lookup(usertable, name);
-
- if (!user) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: no user named %s", name);
- return (NULL);
- }
- /* found the user entry. Find svc node */
- svc = (NODE *) get_value(user, S_svc).pval;
-
- while (svc) {
- if (svc->type == N_svc_cmd && STREQ(svc->value, cmdname)) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: found cmd %s %s node",
- cmdname, cfg_nodestring(svc->type));
- return (svc);
- }
- svc = svc->next;
- }
-
- if (!recurse) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: returns NULL");
- return (NULL);
- }
- /* no matching node. Check containing group */
- if (user->member)
- group = (USER *) hash_lookup(grouptable, user->member);
- else
- group = NULL;
-
- while (group) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: recurse group = %s",
- group->name);
-
- svc = get_value(group, S_svc).pval;
-
- while (svc) {
- if (svc->type == N_svc_cmd && STREQ(svc->value, cmdname)) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: found cmd %s node %s",
- cmdname, cfg_nodestring(svc->type));
- return (svc);
- }
- svc = svc->next;
- }
-
- /* still nothing. Check containing group and so on */
-
- if (group->member)
- group = (USER *) hash_lookup(grouptable, group->member);
- else
- group = NULL;
- }
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_get_cmd_node: returns NULL");
-
- /* no matching cmd node for this user or her containing groups */
- return (NULL);
-}
-
-/* Return an array of character strings representing configured AV
- * pairs, given a username and a service node.
- *
- * In the AV strings returned, manipulate the separator character to
- * indicate which args are optional and which are mandatory.
- *
- * Lastly, indicate what default permission was configured by setting
- * denyp */
-
-char **
-cfg_get_svc_attrs(svcnode, denyp)
-NODE *svcnode;
-int *denyp;
-{
- int i;
- NODE *node;
- char **args;
-
- *denyp = 1;
-
- if (!svcnode)
- return (NULL);
-
- *denyp = (svcnode->dflt == S_deny);
-
- i = 0;
- for (node = svcnode->value; node; node = node->next)
- i++;
-
- args = (char **) tac_malloc(sizeof(char *) * (i + 1));
-
- i = 0;
- for (node = svcnode->value; node; node = node->next) {
- char *arg = tac_strdup(node->value);
- char *p = index(arg, '=');
-
- if (p && node->type == N_optarg)
- *p = '*';
- args[i++] = arg;
- }
- args[i] = NULL;
- return (args);
-}
-
-
-int
-cfg_user_svc_default_is_permit(user)
-char *user;
-
-{
- int permit = cfg_get_intvalue(user, TAC_IS_USER, S_svc_dflt,
- TAC_PLUS_RECURSE);
-
- switch (permit) {
- default: /* default is deny */
- case S_deny:
- return (0);
- case S_permit:
- return (1);
- }
-}
-
-int
-cfg_no_user_permitted()
-{
- if (no_user_dflt == S_permit)
- return (1);
- return (0);
-}
-
-
-char *
-cfg_get_authen_default()
-{
- return (authen_default);
-}
-
-/* For describe authentication method(pam,file,db..etc) */
-int
-cfg_get_authen_default_method()
-{
- return (authen_default_method);
-}
-
-
-/* Return 1 if this user has any ppp services configured. Used for
- authorizing ppp/lcp requests */
-int
-cfg_ppp_is_configured(username, recurse)
- char *username;
- int recurse;
-{
- USER *user, *group;
- NODE *svc;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: username=%s rec=%d",
- username, recurse);
-
- /* find the user/group entry */
- user = (USER *) hash_lookup(usertable, username);
-
- if (!user) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: no user named %s",
- username);
- return (0);
- }
-
- /* found the user entry. Find svc node */
- for(svc = (NODE *) get_value(user, S_svc).pval; svc; svc = svc->next) {
-
- if (svc->type != N_svc_ppp)
- continue;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: found svc ppp %s node",
- svc->value1);
-
- return(1);
- }
-
- if (!recurse) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: returns 0");
- return (0);
- }
-
- /* no matching node. Check containing group */
- if (user->member)
- group = (USER *) hash_lookup(grouptable, user->member);
- else
- group = NULL;
-
- while (group) {
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: recurse group = %s",
- group->name);
-
- for(svc = (NODE *) get_value(group, S_svc).pval; svc; svc = svc->next) {
-
- if (svc->type != N_svc_ppp)
- continue;
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: found svc ppp %s node",
- svc->value1);
-
- return(1);
- }
-
- /* still nothing. Check containing group and so on */
-
- if (group->member)
- group = (USER *) hash_lookup(grouptable, group->member);
- else
- group = NULL;
- }
-
- if (debug & DEBUG_CONFIG_FLAG)
- report(LOG_DEBUG, "cfg_ppp_is_configured: returns 0");
-
- /* no PPP svc nodes for this user or her containing groups */
- return (0);
-}
-
-/* For getting host key */
-char *
-cfg_get_host_key(host)
-char *host;
-{
- return (cfg_get_phvalue(host, S_key));
-}
-