static int check_account(const char *service , const char *tty, const char *user) { int from=0,to=0,fd=-1; char *buffer=NULL; int count=0; TIME here_and_now; int retval=PAM_SUCCESS; here_and_now = time_now(); /* find current time */ do { boolean good=TRUE,intime; /* here we get the service name field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { /* empty line .. ? */ continue; } ++count; good = logic_field(service, buffer, count, is_same); D(("with service: %s", good ? "passes":"fails" )); /* here we get the terminal name field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_TIME_CONF "; no tty entry #%d", count); continue; } good &= logic_field(tty, buffer, count, is_same); D(("with tty: %s", good ? "passes":"fails" )); /* here we get the username field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_TIME_CONF "; no user entry #%d", count); continue; } good &= logic_field(user, buffer, count, is_same); D(("with user: %s", good ? "passes":"fails" )); /* here we get the time field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_TIME_CONF "; no time entry #%d", count); continue; } intime = logic_field(&here_and_now, buffer, count, check_time); D(("with time: %s", intime ? "passes":"fails" )); fd = read_field(fd,&buffer,&from,&to); if (buffer && buffer[0]) { _log_err(PAM_TIME_CONF "; poorly terminated rule #%d", count); continue; } if (good && !intime) { /* * for security parse whole file.. also need to ensure * that the buffer is free()'d and the file is closed. */ retval = PAM_PERM_DENIED; } else { D(("rule passed")); } } while (buffer); return retval; }
static int check_account(const char *service, const char *tty , const char *user) { int from=0,to=0,fd=-1; char *buffer=NULL; int count=0; TIME here_and_now; int retval=PAM_SUCCESS; gid_t *grps; int no_grps; /* * first we get the current list of groups - the application * will have previously done an initgroups(), or equivalent. */ D(("counting supplementary groups")); no_grps = getgroups(0, NULL); /* find the current number of groups */ if (no_grps > 0) { grps = calloc( blk_size(no_grps) , sizeof(gid_t) ); D(("copying current list into grps [%d big]",blk_size(no_grps))); (void) getgroups(no_grps, grps); #ifdef DEBUG { int z; for (z=0; z<no_grps; ++z) { D(("gid[%d]=%d", z, grps[z])); } } #endif } else { D(("no supplementary groups known")); no_grps = 0; grps = NULL; } here_and_now = time_now(); /* find current time */ /* parse the rules in the configuration file */ do { int good=TRUE; /* here we get the service name field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { /* empty line .. ? */ continue; } ++count; D(("working on rule #%d",count)); good = logic_field(service, buffer, count, is_same); D(("with service: %s", good ? "passes":"fails" )); /* here we get the terminal name field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_GROUP_CONF "; no tty entry #%d", count); continue; } good &= logic_field(tty, buffer, count, is_same); D(("with tty: %s", good ? "passes":"fails" )); /* here we get the username field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_GROUP_CONF "; no user entry #%d", count); continue; } good &= logic_field(user, buffer, count, is_same); D(("with user: %s", good ? "passes":"fails" )); /* here we get the time field */ fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_GROUP_CONF "; no time entry #%d", count); continue; } good &= logic_field(&here_and_now, buffer, count, check_time); D(("with time: %s", good ? "passes":"fails" )); fd = read_field(fd,&buffer,&from,&to); if (!buffer || !buffer[0]) { _log_err(PAM_GROUP_CONF "; no listed groups for rule #%d" , count); continue; } /* * so we have a list of groups, we need to turn it into * something to send to setgroups(2) */ if (good) { D(("adding %s to gid list", buffer)); good = mkgrplist(buffer, &grps, no_grps); if (good < 0) { no_grps = 0; } else { no_grps = good; } } /* check the line is terminated correctly */ fd = read_field(fd,&buffer,&from,&to); if (buffer && buffer[0]) { _log_err(PAM_GROUP_CONF "; poorly terminated rule #%d", count); } if (good > 0) { D(("rule #%d passed, added %d groups", count, good)); } else if (good < 0) { retval = PAM_BUF_ERR; } else { D(("rule #%d failed", count)); } } while (buffer); /* now set the groups for the user */ if (no_grps > 0) { int err; D(("trying to set %d groups", no_grps)); #ifdef DEBUG for (err=0; err<no_grps; ++err) { D(("gid[%d]=%d", err, grps[err])); } #endif if ((err = setgroups(no_grps, grps))) { D(("but couldn't set groups %d", err)); _log_err("unable to set the group membership for user (err=%d)" , err); retval = PAM_CRED_ERR; } } if (grps) { /* tidy up */ memset(grps, 0, sizeof(gid_t) * blk_size(no_grps)); _pam_drop(grps); no_grps = 0; } return retval; }