int main(void) { char buf[MAX_SIZE]; fgets(buf, MAX_SIZE, stdin); unsigned long uid; sscanf(buf, "%lu", &uid); fgets(buf, MAX_SIZE, stdin); unsigned long gid[MAX_GID]; int gid_counter = 0; int temp = 0; char *p = buf; int a = 0; printf("%ld\n", uid); while ((a = sscanf(p, "%lu%n", &gid[gid_counter], &temp)) != EOF && a != 0 ) { gid_counter++; p += temp; printf("%ld ", gid[gid_counter - 1]); } unsigned long operation = 0; fgets(buf, MAX_SIZE, stdin); sscanf(buf, "%lo", &operation); while (fgets(buf, MAX_SIZE, stdin) != NULL) { unsigned long file_gid, file_uid; unsigned long permissions; p = buf; sscanf(p, "%lu%lu%lo%n", &file_uid, &file_gid, &permissions, &temp); p += temp; p = cat_space(p); if (uid == file_uid) { if (has_permissions(operation, permissions, USER)) { printf("%s\n", p); } } else { if (is_in_group(gid, gid_counter, file_gid)) { if (has_permissions(operation, permissions, GROUP)) { printf("%s\n", p); } } else { if (has_permissions(operation, permissions, NOBODY)) { printf("%s\n", p); } } } } return 0; }
rpc_state* handle_msg_prepare(const msg_prepare_t *p_msg_prep) { SAFE_ASSERT(p_msg_prep->h->t == MPAXOS__MSG_HEADER__MSGTYPE_T__PREPARE); // This is the msg_promise for response msg_promise_t msg_prom = MPAXOS__MSG_PROMISE__INIT; msg_header_t msg_header = MPAXOS__MSG_HEADER__INIT; msg_prom.h = &msg_header; msg_prom.h->t = MPAXOS__MSG_HEADER__MSGTYPE_T__PROMISE; msg_prom.h->tid = p_msg_prep->h->tid; msg_prom.h->nid = get_local_nid(); msg_prom.n_ress = 0; msg_prom.ress = (response_t **) calloc(p_msg_prep->n_rids, sizeof(response_t *)); for (int i = 0; i < p_msg_prep->n_rids; i++) { roundid_t *rid = p_msg_prep->rids[i]; if (!is_in_group(rid->gid)) { //Check for every requested group in the prepare message. //Skip for the groups which I don't belong to. continue; } // For those I belong to, add response. response_t *p_res = (response_t *) calloc(sizeof(response_t), 1); msg_prom.ress[msg_prom.n_ress] = p_res; mpaxos__response_t__init(p_res); p_res->rid = rid; accp_info_t* ainfo = get_accp_info(rid->gid, rid->sid); SAFE_ASSERT(ainfo != NULL); // lock on this accp info apr_thread_mutex_lock(ainfo->mx); // Check if the ballot id is larger. // must be greater than. or must be prepared before by the same proposer (TODO) if (rid->bid > ainfo->bid_max) { p_res->ack = MPAXOS__ACK_ENUM__SUCCESS; ainfo->bid_max = rid->bid; LOG_DEBUG("prepare is ok. bid: %"PRIx64 ", seen max bid: %"PRIx64, rid->bid, ainfo->bid_max); } else if (rid->bid < ainfo->bid_max) { p_res->ack = MPAXOS__ACK_ENUM__ERR_BID; LOG_DEBUG("prepare is not ok. bid: %"PRIx64 ", seen max bid: %"PRIx64, rid->bid, ainfo->bid_max); } else { LOG_DEBUG("receive an undefined bid. bid: %"PRIx64 ", seen max bid: %"PRIx64, rid->bid, ainfo->bid_max); SAFE_ASSERT(0); } // Check if already accepted any proposals. // Add them to the response as well. apr_array_header_t *arr_prop = ainfo->arr_prop; p_res->n_props = arr_prop->nelts; LOG_DEBUG("there is %d proposals i have aready got.", arr_prop->nelts); p_res->props = (proposal_t**) malloc(p_res->n_props * sizeof(proposal_t *)); for (int i = 0; i < p_res->n_props; i++) { proposal_t *oldp = ((proposal_t **)arr_prop->elts)[i]; p_res->props[i] = oldp; } msg_prom.n_ress++; apr_thread_mutex_unlock(ainfo->mx); } // Send back the promise message size_t sz_msg = mpaxos__msg_promise__get_packed_size(&msg_prom); log_message_res("send", "PROMISE", msg_prom.h, msg_prom.ress, msg_prom.n_ress, sz_msg); uint8_t *buf = (uint8_t *) malloc(sz_msg); mpaxos__msg_promise__pack(&msg_prom, buf); rpc_state *ret_state = (rpc_state*) malloc(sizeof(rpc_state)); ret_state->raw_output = buf; ret_state->sz_output = sz_msg; for (int i = 0; i < msg_prom.n_ress; i++) { free(msg_prom.ress[i]->props); free(msg_prom.ress[i]); } free(msg_prom.ress); return ret_state; }
rpc_state* handle_msg_accept(const msg_accept_t *msg_accp) { SAFE_ASSERT(msg_accp->h->t == MPAXOS__MSG_HEADER__MSGTYPE_T__ACCEPT); // This is the msg_accepted for response msg_accepted_t msg_accd = MPAXOS__MSG_ACCEPTED__INIT; msg_header_t msg_header = MPAXOS__MSG_HEADER__INIT; msg_accd.h = &msg_header; msg_accd.h->t = MPAXOS__MSG_HEADER__MSGTYPE_T__ACCEPTED; msg_accd.h->tid = msg_accp->h->tid; msg_accd.h->nid = get_local_nid(); msg_accd.n_ress = 0; msg_accd.ress = (response_t **) malloc(msg_accp->prop->n_rids * sizeof(response_t *)); for (int i = 0; i < msg_accp->prop->n_rids; i++) { roundid_t *rid = msg_accp->prop->rids[i]; if (!is_in_group(rid->gid)) { continue; } // For those I belong to, add resoponse. response_t *response = (response_t *) malloc(sizeof(response_t)); msg_accd.ress[msg_accd.n_ress] = response; mpaxos__response_t__init(response); response->rid = rid; accp_info_t *ainfo = get_accp_info(rid->gid, rid->sid); SAFE_ASSERT(ainfo != NULL); apr_thread_mutex_lock(ainfo->mx); // Check if the ballot id is larger. ballotid_t maxbid = ainfo->bid_max; if (rid->bid >= maxbid) { response->ack = MPAXOS__ACK_ENUM__SUCCESS; record_accepted(rid, msg_accp->prop); proposal_t **p = apr_array_push(ainfo->arr_prop); // *p = apr_pcalloc(ainfo->mp, sizeof(proposal_t)); // prop_cpy(*p, msg_accp->prop, ainfo->mp); *p = prop_copy(msg_accp->prop); } else if (rid->bid < maxbid) { response->ack = MPAXOS__ACK_ENUM__ERR_BID; } else { SAFE_ASSERT(0); } //FIXME whether or not to add proposals in the message. //now not msg_accd.n_ress++; apr_thread_mutex_unlock(ainfo->mx); } // send back the msg_accepted. size_t len = mpaxos__msg_accepted__get_packed_size(&msg_accd); log_message_res("send", "ACCEPTED", msg_accd.h, msg_accd.ress, msg_accd.n_ress, len); uint8_t *buf = (uint8_t *) malloc(len); mpaxos__msg_accepted__pack(&msg_accd, buf); for (int i = 0; i < msg_accd.n_ress; i++) { free(msg_accd.ress[i]); } free(msg_accd.ress); rpc_state *ret_state = (rpc_state*) malloc(sizeof(rpc_state)); ret_state->raw_output = buf; ret_state->sz_output = len; return ret_state; }
static int parse_config_file(const char *uname, int ctrl, struct pam_limit_s *pl) { FILE *fil; char buf[LINE_LENGTH]; #define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE /* check for the LIMITS_FILE */ if (ctrl & PAM_DEBUG_ARG) _pam_log(LOG_DEBUG,"reading settings from '%s'", CONF_FILE); fil = fopen(CONF_FILE, "r"); if (fil == NULL) { _pam_log (LOG_WARNING, "can not read settings from %s", CONF_FILE); return PAM_SERVICE_ERR; } #undef CONF_FILE /* init things */ memset(buf, 0, sizeof(buf)); /* start the show */ while (fgets(buf, LINE_LENGTH, fil) != NULL) { char domain[LINE_LENGTH]; char ltype[LINE_LENGTH]; char item[LINE_LENGTH]; char value[LINE_LENGTH]; int i,j; char *tptr; tptr = buf; /* skip the leading white space */ while (*tptr && isspace(*tptr)) tptr++; strncpy(buf, tptr, sizeof(buf)-1); buf[sizeof(buf)-1] = '\0'; /* Rip off the comments */ tptr = strchr(buf,'#'); if (tptr) *tptr = '\0'; /* Rip off the newline char */ tptr = strchr(buf,'\n'); if (tptr) *tptr = '\0'; /* Anything left ? */ if (!strlen(buf)) { memset(buf, 0, sizeof(buf)); continue; } memset(domain, 0, sizeof(domain)); memset(ltype, 0, sizeof(ltype)); memset(item, 0, sizeof(item)); memset(value, 0, sizeof(value)); i = sscanf(buf,"%s%s%s%s", domain, ltype, item, value); D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]", i, domain, ltype, item, value)); for(j=0; j < strlen(domain); j++) domain[j]=tolower(domain[j]); for(j=0; j < strlen(ltype); j++) ltype[j]=tolower(ltype[j]); for(j=0; j < strlen(item); j++) item[j]=tolower(item[j]); for(j=0; j < strlen(value); j++) value[j]=tolower(value[j]); if (i == 4) { /* a complete line */ if (strcmp(uname, domain) == 0) /* this user have a limit */ process_limit(LIMITS_DEF_USER, ltype, item, value, ctrl, pl); else if (domain[0]=='@') { _pam_log(LOG_DEBUG, "checking if %s is in group %s", uname, domain + 1); if (is_in_group(uname, domain+1)) process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl, pl); } else if (strcmp(domain, "*") == 0) process_limit(LIMITS_DEF_DEFAULT, ltype, item, value, ctrl, pl); } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */ if (strcmp(uname, domain) == 0) { _pam_log(LOG_DEBUG, "no limits for '%s'", uname); fclose(fil); return PAM_IGNORE; } else if (domain[0] == '@' && is_in_group(uname, domain+1)) { _pam_log(LOG_DEBUG, "no limits for '%s' in group '%s'", uname, domain+1); fclose(fil); return PAM_IGNORE; } } else { _pam_log(LOG_DEBUG,"invalid line '%s' - skipped", buf); } } fclose(fil); return PAM_SUCCESS; }
/* Counts the number of user logins and check against the limit*/ static int check_logins(const char *name, int limit, int ctrl, struct pam_limit_s *pl) { struct utmp *ut; unsigned int count; if (ctrl & PAM_DEBUG_ARG) { _pam_log(LOG_DEBUG, "checking logins for '%s' (maximum of %d)\n", name, limit); } if (limit < 0) return 0; /* no limits imposed */ if (limit == 0) /* maximum 0 logins ? */ { _pam_log(LOG_WARNING, "No logins allowed for '%s'\n", name); return LOGIN_ERR; } setutent(); /* Because there is no definition about when an application actually adds a utmp entry, some applications bizarrely do the utmp call before the have PAM authenticate them to the system: you're logged it, sort of...? Anyway, you can use the "utmp_early" module argument in your PAM config file to make allowances for this sort of problem. (There should be a PAM standard for this, since if a module wants to actually map a username then any early utmp entry will be for the unmapped name = broken.) */ if (ctrl & PAM_UTMP_EARLY) { count = 0; } else { count = 1; } while((ut = getutent())) { #ifdef USER_PROCESS if (ut->ut_type != USER_PROCESS) { continue; } #endif if (ut->UT_USER[0] == '\0') { continue; } if (!pl->flag_numsyslogins) { if ((pl->login_limit_def == LIMITS_DEF_USER) && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) { continue; } if ((pl->login_limit_def == LIMITS_DEF_GROUP) && !is_in_group(ut->UT_USER, name)) { continue; } } if (++count > limit) { break; } } endutent(); if (count > limit) { if (name) { _pam_log(LOG_WARNING, "Too many logins (max %d) for %s", limit, name); } else { _pam_log(LOG_WARNING, "Too many system logins (max %d)", limit); } return LOGIN_ERR; } return 0; }
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, int report) { int updated = 0; STRUCT_STAT st2; int change_uid, change_gid; extern int am_daemon; if (dry_run) return 0; if (!st) { if (link_stat(fname,&st2) != 0) { rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno)); return 0; } st = &st2; } if (preserve_times && !S_ISLNK(st->st_mode) && st->st_mtime != file->modtime) { /* don't complain about not setting times on directories because some filesystems can't do it */ if (set_modtime(fname,file->modtime) != 0 && !S_ISDIR(st->st_mode)) { rprintf(FERROR,"failed to set times on %s : %s\n", fname,strerror(errno)); return 0; } else { updated = 1; } } change_uid = am_root && preserve_uid && st->st_uid != file->uid; change_gid = !am_daemon && preserve_gid && file->gid != (gid_t) -1 && \ st->st_gid != file->gid; if (change_gid && !am_root) { /* enforce bsd-style group semantics: non-root can only change to groups that the user is a member of */ change_gid = is_in_group(file->gid); } if (change_uid || change_gid) { if (do_lchown(fname, change_uid?file->uid:st->st_uid, change_gid?file->gid:st->st_gid) != 0) { /* shouldn't have attempted to change uid or gid unless have the privilege */ rprintf(FERROR,"chown %s : %s\n", fname,strerror(errno)); return 0; } updated = 1; } #ifdef HAVE_CHMOD if (!S_ISLNK(st->st_mode)) { int file_mode; if (preserve_perms) file_mode = file->mode; else file_mode = file->mode & ACCESSPERMS; if (st->st_mode != file->mode) { updated = 1; if (do_chmod(fname,file_mode) != 0) { rprintf(FERROR,"failed to set permissions on %s : %s\n", fname,strerror(errno)); return 0; } } } #endif if (verbose > 1 && report) { if (updated) rprintf(FINFO,"%s\n",fname); else rprintf(FINFO,"%s is uptodate\n",fname); } return updated; }