/** * tree - get the coalescent * * @param N - sample size * @param theta - mutation rate * @param get_newick - get newick representation * * @param Tb - time for population "bottleneck" (can also model * expansion; see parameter f) * * @param f - fraction of population size at Tb compared to current * size N_0; in other words, N_b = f * N_0. When f>1 a bottleneck is * modelled, when f<1 an expansion * * @return SEXP vector containing TMRCA, TBL, S_n and possibly newick * representation of tree * */ SEXP tree(SEXP N, SEXP theta, SEXP get_newick, SEXP Tb, SEXP f) { SEXP ans, NEWICK; SEXP TMRCA = PROTECT(allocVector(REALSXP, 1)); SEXP TBL = PROTECT(allocVector(REALSXP, 1)); SEXP NMUT = PROTECT(allocVector(INTSXP, 1)); struct Node *n; n = coalescent_tree(asInteger(N), asReal(theta), asReal(Tb), asReal(f)); char *newick_ptr = "NA"; if ((boolean) asInteger(get_newick)) newick_ptr = newick(n); PROTECT(NEWICK = allocVector(STRSXP, 1)); SET_STRING_ELT(NEWICK, 0, mkChar(newick_ptr)); ans = PROTECT(allocVector(VECSXP, 4)); NMUT = ScalarInteger(segregating_sites(n)); TMRCA = ScalarReal(tmrca(n)); TBL = ScalarReal(total_branch_length(n)); SET_VECTOR_ELT(ans, 0, TMRCA); SET_VECTOR_ELT(ans, 1, TBL); SET_VECTOR_ELT(ans, 2, NMUT); SET_VECTOR_ELT(ans, 3, NEWICK); UNPROTECT(5); // Clean up memory remove_tree(n); return (ans); }
int remove_homedir(TALLOC_CTX *mem_ctx, const char *homedir, const char *maildir, const char *username, uid_t uid, bool force) { int ret; ret = remove_mail_spool(mem_ctx, maildir, username, uid, force); if (ret != EOK) { DEBUG(1, ("Cannot remove user's mail spool\n")); /* Should this be fatal? I don't think so. Maybe convert to ERROR? */ } if (force == false && is_owner(uid, homedir) == -1) { DEBUG(1, ("Not removing home dir - not owned by user\n")); return EPERM; } /* Remove the tree */ ret = remove_tree(homedir); if (ret != EOK) { DEBUG(1, ("Cannot remove homedir %s: %d\n", homedir, ret)); return ret; } return EOK; }
/** * Updates root of tree according to col played * * @param board - after performing move * @param col - last chosen column * @param row - last chosen row * @param depth - max depth chosen */ void update_tree(minmax_tree *tree, int col, int row, int depth) { element* iterator; vertex* current_root = tree->root; if (current_root->children != NULL) { iterator = current_root->children->head; while ((iterator != NULL) && (!((iterator->node->current_move->j == col) && (iterator->node->current_move->i == row) ))) { iterator = iterator->next; } if (iterator != NULL) { // change to the new root tree->root = iterator->node; // remove the rest of the tree: // connect the previous and next childs together and then remove the last root if (iterator->prev != NULL) { iterator->prev->next = iterator->next; } else { current_root->children->head = iterator->next; } if (iterator->next != NULL) { iterator->next->prev = iterator->prev; } else { current_root->children->tail = iterator->prev; } remove_tree(current_root); free(iterator); } // no children - just change the root } else { tree->root->current_move->i = row; tree->root->current_move->j = col; tree->root->value = (-1) * (tree->root->value); } }
/* choose the best next move for the computer, according to minimax */ int get_computer_move(int * game_matrix,int depth,linked_list (*create_children)(int *gameMatrix, int player,int *error)) { int cMove = 0,error=0; vertex root = build_tree(game_matrix, -1,create_children); if (root == NULL){ printf("make root failed\n"); return -1; } alphaBeta(root,INT_MIN,INT_MAX,-1,0,depth,create_children,&error); if(error==-1){ printf("alphaBeta failed\n"); remove_tree(root, 1,1); return -1; } cMove = getMove(root); remove_tree(root, 1,0); return cMove; }
/*return the move that this vertex represents*/ int getMove(vertex root) { element cur_elem; int movement=0; for (cur_elem = root->edges->head; cur_elem != NULL; cur_elem = cur_elem->next) { if (cur_elem->node->score == root->score) { movement=cur_elem->node->mov_col; for (; cur_elem != NULL;cur_elem = cur_elem->next){ remove_tree(cur_elem->node, 0,0); } return movement; } remove_tree(cur_elem->node, 0,0); } return 0; }
/* deletes list */ void deleteList(element head,int is_nodes,int recursivly){ if(head==NULL){ return; } deleteList(head->next,is_nodes,recursivly); if (recursivly==1){ remove_tree(head->node,0,recursivly); } free(head); }
/* we use this to get the first move when AI plays first */ int get_suggested_move(int * game_matrix, int depth,linked_list (*create_children)(int *gameMatrix, int player,int *error)) { int cMove = 0,error=0; /* build tree */ vertex root = build_tree(game_matrix, 1,create_children); if (root == NULL){ printf("make root failed\n"); return -1; } /* update scores in the tree */ alphaBeta(root,INT_MIN,INT_MAX,1,0,depth,create_children,&error); if(error==-1){ printf("alphaBeta failed\n"); remove_tree(root, 1,1); return -1; } /* find best move */ cMove = getMove(root); /* destroy tree */ remove_tree(root, 1,0); return cMove; }
int read_input() { failed = 0; remove_tree(root); root = newnode(); for(;;) { if(scanf("%s", s) != 1) return 0; if(!strcmp(s, "()")) break; int v; sscanf(&s[1], "%d", &v); addnode(v, strchr(s, ',')+1); } return 1; }
/** * Frees all vertexts, elements, lists under node, recursively */ void remove_tree(vertex* current_node) { element* previous; element* nextush; if ((current_node != NULL) && (current_node->children != NULL)) { previous = current_node->children->head; while (previous != NULL) { remove_tree(previous->node); nextush = previous->next; free(previous); previous = nextush; } free(current_node->children); } free(current_node->current_move); free(current_node); }
int main(int argc, const char * argv[]) { // srand((unsigned int)time(NULL)); srand(1); for (size_t k = 0; k < 1000000; k++) { tree_node_t *t = create_tree(); for (key_t i = 0; i < 100; i++) { key_t j = (key_t)rand(); insert(t, j, t); } // brass-ds-redblack-trees | sed 's/0x//g' | dot -Tpdf -o 1.pdf; open 1.pdf // print_tree(t); remove_tree(t); } free_tree(); return 0; }
static int remove_tcbdir (const char *user_name, uid_t user_id) { char *buf; int ret = 0; size_t bufsize = (sizeof TCB_DIR) + strlen (user_name) + 2; if (!getdef_bool ("USE_TCB")) { return 0; } buf = malloc (buflen); if (NULL == buf) { fprintf (stderr, _("%s: Can't allocate memory, " "tcb entry for %s not removed.\n"), Prog, user_name); return 1; } snprintf (buf, buflen, TCB_DIR "/%s", user_name); if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) { fprintf (stderr, _("%s: Cannot drop privileges: %s\n"), Prog, strerror (errno)); shadowtcb_gain_priv (); free (buf); return 1; } /* Only remove directory contents with dropped privileges. * We will regain them and remove the user's tcb directory afterwards. */ if (remove_tree (buf, false) != 0) { fprintf (stderr, _("%s: Cannot remove the content of %s: %s\n"), Prog, buf, strerror (errno)); shadowtcb_gain_priv (); free (buf); return 1; } shadowtcb_gain_priv (); free (buf); if (shadowtcb_remove (user_name) == SHADOWTCB_FAILURE) { fprintf (stderr, _("%s: Cannot remove tcb files for %s: %s\n"), Prog, user_name, strerror (errno)); ret = 1; } return ret; }
/* constructs the root and it's children. * once this is assured, alphabeta may continue construction */ vertex build_tree(int * game_matrix, int player,linked_list (*create_children)(int *gameMatrix, int player,int *error)) { linked_list new_children=NULL; int error=0; /* new root */ vertex root = make_node(0, game_matrix,0); if (root == NULL){ printf("ERROR: can't create root\n"); return NULL; } new_children=create_children(root->game_state, player,&error); if (error<0){ printf("ERROR: can't create children for root\n"); remove_tree(root,1,0); return NULL; } root->edges=new_children; return root; }
int remove_tree (const char *root, bool remove_root) { char *new_name = NULL; int err = 0; struct DIRECT *ent; struct stat sb; DIR *dir; /* * Open the source directory and read each entry. Every file * entry in the directory is copied with the UID and GID set * to the provided values. As an added security feature only * regular files (and directories ...) are copied, and no file * is made set-ID. */ dir = opendir (root); if (NULL == dir) { return -1; } while ((ent = readdir (dir))) { size_t new_len = strlen (root) + strlen (ent->d_name) + 2; /* * Skip the "." and ".." entries */ if (strcmp (ent->d_name, ".") == 0 || strcmp (ent->d_name, "..") == 0) { continue; } /* * Make the filename for the current entry. */ free (new_name); new_name = (char *) malloc (new_len); if (NULL == new_name) { err = -1; break; } (void) snprintf (new_name, new_len, "%s/%s", root, ent->d_name); if (LSTAT (new_name, &sb) == -1) { continue; } if (S_ISDIR (sb.st_mode)) { /* * Recursively delete this directory. */ if (remove_tree (new_name, true) != 0) { err = -1; break; } } else { /* * Delete the file. */ if (unlink (new_name) != 0) { err = -1; break; } } } if (NULL != new_name) { free (new_name); } (void) closedir (dir); if (remove_root && (0 == err)) { if (rmdir (root) != 0) { err = -1; } } return err; }
/* * process_flags - perform command line argument setting * * process_flags() interprets the command line arguments and sets the * values that the user will be created with accordingly. The values * are checked for sanity. */ static void process_flags (int argc, char **argv) { const struct group *grp; const struct passwd *pwd; const struct spwd *spwd = NULL; int anyflag = 0; int arg; if (argc == 1 || argv[argc - 1][0] == '-') usage (); if (!(pwd = getpwnam (argv[argc - 1]))) { fprintf (stderr, _("%s: user %s does not exist\n"), Prog, argv[argc - 1]); exit (E_NOTFOUND); } user_name = argv[argc - 1]; user_id = pwd->pw_uid; user_gid = pwd->pw_gid; user_comment = xstrdup (pwd->pw_gecos); user_home = xstrdup (pwd->pw_dir); user_shell = xstrdup (pwd->pw_shell); #ifdef WITH_AUDIT user_newname = user_name; user_newid = user_id; user_newgid = user_gid; user_newcomment = user_comment; user_newhome = user_home; user_newshell = user_shell; #endif #ifdef USE_NIS /* * Now make sure it isn't an NIS user. */ if (__ispwNIS ()) { char *nis_domain; char *nis_master; fprintf (stderr, _("%s: user %s is a NIS user\n"), Prog, user_name); if (!yp_get_default_domain (&nis_domain) && !yp_master (nis_domain, "passwd.byname", &nis_master)) { fprintf (stderr, _("%s: %s is the NIS master\n"), Prog, nis_master); } exit (E_NOTFOUND); } #endif if (is_shadow_pwd && (spwd = getspnam (user_name))) { user_expire = spwd->sp_expire; user_inactive = spwd->sp_inact; #ifdef WITH_AUDIT user_newexpire = user_expire; user_newinactive = user_inactive; #endif } { /* * Parse the command line options. */ int c; static struct option long_options[] = { {"append", required_argument, NULL, 'a'}, {"comment", required_argument, NULL, 'c'}, {"home", required_argument, NULL, 'd'}, {"expiredate", required_argument, NULL, 'e'}, {"inactive", required_argument, NULL, 'f'}, {"gid", required_argument, NULL, 'g'}, {"groups", required_argument, NULL, 'G'}, {"help", no_argument, NULL, 'h'}, {"login", required_argument, NULL, 'l'}, {"lock", no_argument, NULL, 'L'}, {"move-home", no_argument, NULL, 'm'}, {"non-unique", no_argument, NULL, 'o'}, {"password", required_argument, NULL, 'p'}, {"shell", required_argument, NULL, 's'}, {"uid", required_argument, NULL, 'u'}, {"unlock", no_argument, NULL, 'U'}, {NULL, 0, NULL, '\0'} }; while ((c = getopt_long (argc, argv, "ac:d:e:f:g:G:l:Lmop:s:u:U", long_options, NULL)) != -1) { switch (c) { case 'a': aflg++; break; case 'c': if (!VALID (optarg)) { fprintf (stderr, _("%s: invalid field `%s'\n"), Prog, optarg); exit (E_BAD_ARG); } #ifdef WITH_AUDIT user_newcomment = optarg; #else user_comment = optarg; #endif cflg++; break; case 'd': if (!VALID (optarg)) { fprintf (stderr, _("%s: invalid field `%s'\n"), Prog, optarg); exit (E_BAD_ARG); } dflg++; user_newhome = optarg; break; case 'e': if (*optarg) { #ifdef WITH_AUDIT user_newexpire = strtoday (optarg); if (user_newexpire == -1) { #else user_expire = strtoday (optarg); if (user_expire == -1) { #endif fprintf (stderr, _ ("%s: invalid date `%s'\n"), Prog, optarg); exit (E_BAD_ARG); } #ifdef WITH_AUDIT user_newexpire *= DAY / SCALE; #else user_expire *= DAY / SCALE; #endif } else #ifdef WITH_AUDIT user_newexpire = -1; #else user_expire = -1; #endif eflg++; break; case 'f': #ifdef WITH_AUDIT user_newinactive = get_number (optarg); #else user_inactive = get_number (optarg); #endif fflg++; break; case 'g': grp = getgr_nam_gid (optarg); if (!grp) { fprintf (stderr, _("%s: unknown group %s\n"), Prog, optarg); exit (E_NOTFOUND); } user_newgid = grp->gr_gid; gflg++; break; case 'G': if (get_groups (optarg)) exit (E_NOTFOUND); Gflg++; break; case 'l': if (!check_user_name (optarg)) { fprintf (stderr, _("%s: invalid field `%s'\n"), Prog, optarg); exit (E_BAD_ARG); } /* * If the name does not really change, we mustn't * set the flag as this will cause rather serious * problems later! */ if (strcmp (user_name, optarg)) lflg++; user_newname = optarg; break; case 'L': if (Uflg || pflg) usage (); Lflg++; break; case 'm': if (!dflg) usage (); mflg++; break; case 'o': if (!uflg) usage (); oflg++; break; case 'p': if (Lflg || Uflg) usage (); user_pass = optarg; pflg++; break; case 's': if (!VALID (optarg)) { fprintf (stderr, _("%s: invalid field `%s'\n"), Prog, optarg); exit (E_BAD_ARG); } #ifdef WITH_AUDIT user_newshell = optarg; #else user_shell = optarg; #endif sflg++; break; case 'u': user_newid = get_id (optarg); uflg++; break; case 'U': if (Lflg && pflg) usage (); Uflg++; break; default: usage (); } anyflag++; } } if (anyflag == 0) { fprintf (stderr, _("%s: no flags given\n"), Prog); exit (E_USAGE); } if (!is_shadow_pwd && (eflg || fflg)) { fprintf (stderr, _ ("%s: shadow passwords required for -e and -f\n"), Prog); exit (E_USAGE); } if (optind != argc - 1) usage (); if (aflg && (!Gflg)) { fprintf (stderr, _("%s: -a flag is ONLY allowed with the -G flag\n"), Prog); usage (); exit (E_USAGE); } if (dflg && strcmp (user_home, user_newhome) == 0) dflg = mflg = 0; if (uflg && user_id == user_newid) uflg = oflg = 0; if (lflg && getpwnam (user_newname)) { fprintf (stderr, _("%s: user %s exists\n"), Prog, user_newname); exit (E_NAME_IN_USE); } if (uflg && !oflg && getpwuid (user_newid)) { fprintf (stderr, _("%s: uid %lu is not unique\n"), Prog, (unsigned long) user_newid); exit (E_UID_IN_USE); } } /* * close_files - close all of the files that were opened * * close_files() closes all of the files that were opened for this new * user. This causes any modified entries to be written out. */ static void close_files (void) { if (!pw_close ()) { fprintf (stderr, _("%s: cannot rewrite password file\n"), Prog); fail_exit (E_PW_UPDATE); } if (is_shadow_pwd && !spw_close ()) { fprintf (stderr, _("%s: cannot rewrite shadow password file\n"), Prog); fail_exit (E_PW_UPDATE); } if (is_shadow_pwd) spw_unlock (); (void) pw_unlock (); /* * Close the DBM and/or flat files */ endpwent (); endspent (); endgrent (); #ifdef SHADOWGRP endsgent (); #endif } /* * open_files - lock and open the password files * * open_files() opens the two password files. */ static void open_files (void) { if (!pw_lock ()) { fprintf (stderr, _("%s: unable to lock password file\n"), Prog); exit (E_PW_UPDATE); } if (!pw_open (O_RDWR)) { fprintf (stderr, _("%s: unable to open password file\n"), Prog); fail_exit (E_PW_UPDATE); } if (is_shadow_pwd && !spw_lock ()) { fprintf (stderr, _("%s: cannot lock shadow password file\n"), Prog); fail_exit (E_PW_UPDATE); } if (is_shadow_pwd && !spw_open (O_RDWR)) { fprintf (stderr, _("%s: cannot open shadow password file\n"), Prog); fail_exit (E_PW_UPDATE); } } /* * usr_update - create the user entries * * usr_update() creates the password file entries for this user and * will update the group entries if required. */ static void usr_update (void) { struct passwd pwent; const struct passwd *pwd; struct spwd spent; const struct spwd *spwd = NULL; /* * Locate the entry in /etc/passwd, which MUST exist. */ pwd = pw_locate (user_name); if (!pwd) { fprintf (stderr, _("%s: %s not found in /etc/passwd\n"), Prog, user_name); fail_exit (E_NOTFOUND); } pwent = *pwd; new_pwent (&pwent); /* * Locate the entry in /etc/shadow. It doesn't have to exist, and * won't be created if it doesn't. */ if (is_shadow_pwd && (spwd = spw_locate (user_name))) { spent = *spwd; new_spent (&spent); } if (lflg || uflg || gflg || cflg || dflg || sflg || pflg || Lflg || Uflg) { if (!pw_update (&pwent)) { fprintf (stderr, _("%s: error changing password entry\n"), Prog); fail_exit (E_PW_UPDATE); } if (lflg && !pw_remove (user_name)) { fprintf (stderr, _("%s: error removing password entry\n"), Prog); fail_exit (E_PW_UPDATE); } } if (spwd && (lflg || eflg || fflg || pflg || Lflg || Uflg)) { if (!spw_update (&spent)) { fprintf (stderr, _ ("%s: error adding new shadow password entry\n"), Prog); fail_exit (E_PW_UPDATE); } if (lflg && !spw_remove (user_name)) { fprintf (stderr, _ ("%s: error removing shadow password entry\n"), Prog); fail_exit (E_PW_UPDATE); } } } /* * move_home - move the user's home directory * * move_home() moves the user's home directory to a new location. The * files will be copied if the directory cannot simply be renamed. */ static void move_home (void) { struct stat sb; if (mflg && stat (user_home, &sb) == 0) { /* * Don't try to move it if it is not a directory * (but /dev/null for example). --marekm */ if (!S_ISDIR (sb.st_mode)) return; if (access (user_newhome, F_OK) == 0) { fprintf (stderr, _("%s: directory %s exists\n"), Prog, user_newhome); fail_exit (E_HOMEDIR); } else if (rename (user_home, user_newhome)) { if (errno == EXDEV) { if (mkdir (user_newhome, sb.st_mode & 0777)) { fprintf (stderr, _ ("%s: can't create %s\n"), Prog, user_newhome); } if (chown (user_newhome, sb.st_uid, sb.st_gid)) { fprintf (stderr, _("%s: can't chown %s\n"), Prog, user_newhome); rmdir (user_newhome); fail_exit (E_HOMEDIR); } if (copy_tree (user_home, user_newhome, uflg ? user_newid : -1, gflg ? user_newgid : -1) == 0) { if (remove_tree (user_home) != 0 || rmdir (user_home) != 0) fprintf (stderr, _ ("%s: warning: failed to completely remove old home directory %s"), Prog, user_home); #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "moving home directory", user_newname, user_newid, 1); #endif return; } (void) remove_tree (user_newhome); (void) rmdir (user_newhome); } fprintf (stderr, _ ("%s: cannot rename directory %s to %s\n"), Prog, user_home, user_newhome); fail_exit (E_HOMEDIR); } #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "moving home directory", user_newname, user_newid, 1); #endif } if (uflg || gflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing home directory owner", user_newname, user_newid, 1); #endif chown (dflg ? user_newhome : user_home, uflg ? user_newid : user_id, gflg ? user_newgid : user_gid); } } /* * update_files - update the lastlog and faillog files */ static void update_files (void) { struct lastlog ll; struct faillog fl; int fd; /* * Relocate the "lastlog" entries for the user. The old entry is * left alone in case the UID was shared. It doesn't hurt anything * to just leave it be. */ if ((fd = open (LASTLOG_FILE, O_RDWR)) != -1) { lseek (fd, (off_t) user_id * sizeof ll, SEEK_SET); if (read (fd, (char *) &ll, sizeof ll) == sizeof ll) { lseek (fd, (off_t) user_newid * sizeof ll, SEEK_SET); write (fd, (char *) &ll, sizeof ll); } close (fd); } /* * Relocate the "faillog" entries in the same manner. */ if ((fd = open (FAILLOG_FILE, O_RDWR)) != -1) { lseek (fd, (off_t) user_id * sizeof fl, SEEK_SET); if (read (fd, (char *) &fl, sizeof fl) == sizeof fl) { lseek (fd, (off_t) user_newid * sizeof fl, SEEK_SET); write (fd, (char *) &fl, sizeof fl); } close (fd); } } #ifndef NO_MOVE_MAILBOX /* * This is the new and improved code to carefully chown/rename the user's * mailbox. Maybe I am too paranoid but the mail spool dir sometimes * happens to be mode 1777 (this makes mail user agents work without * being setgid mail, but is NOT recommended; they all should be fixed * to use movemail). --marekm */ static void move_mailbox (void) { const char *maildir; char mailfile[1024], newmailfile[1024]; int fd; struct stat st; maildir = getdef_str ("MAIL_DIR"); #ifdef MAIL_SPOOL_DIR if (!maildir && !getdef_str ("MAIL_FILE")) maildir = MAIL_SPOOL_DIR; #endif if (!maildir) return; /* * O_NONBLOCK is to make sure open won't hang on mandatory locks. * We do fstat/fchown to make sure there are no races (someone * replacing /var/spool/mail/luser with a hard link to /etc/passwd * between stat and chown). --marekm */ snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name); fd = open (mailfile, O_RDONLY | O_NONBLOCK, 0); if (fd < 0) { /* no need for warnings if the mailbox doesn't exist */ if (errno != ENOENT) perror (mailfile); return; } if (fstat (fd, &st) < 0) { perror ("fstat"); close (fd); return; } if (st.st_uid != user_id) { /* better leave it alone */ fprintf (stderr, _("%s: warning: %s not owned by %s\n"), Prog, mailfile, user_name); close (fd); return; } if (uflg) { if (fchown (fd, user_newid, (gid_t) - 1) < 0) { perror (_("failed to change mailbox owner")); } #ifdef WITH_AUDIT else { audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing mail file owner", user_newname, user_newid, 1); } #endif } close (fd); if (lflg) { snprintf (newmailfile, sizeof newmailfile, "%s/%s", maildir, user_newname); if (link (mailfile, newmailfile) || unlink (mailfile)) { perror (_("failed to rename mailbox")); } #ifdef WITH_AUDIT else { audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing mail file name", user_newname, user_newid, 1); } #endif } } #endif /* * main - usermod command */ int main (int argc, char **argv) { int grp_err = 0; #ifdef USE_PAM pam_handle_t *pamh = NULL; struct passwd *pampw; int retval; #endif #ifdef WITH_AUDIT audit_help_open (); #endif /* * Get my name so that I can use it to report errors. */ Prog = Basename (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); sys_ngroups = sysconf (_SC_NGROUPS_MAX); user_groups = malloc ((1 + sys_ngroups) * sizeof (char *)); user_groups[0] = (char *) 0; OPENLOG ("usermod"); is_shadow_pwd = spw_file_present (); #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif process_flags (argc, argv); #ifdef USE_PAM retval = PAM_SUCCESS; pampw = getpwuid (getuid ()); if (pampw == NULL) { retval = PAM_USER_UNKNOWN; } if (retval == PAM_SUCCESS) { retval = pam_start ("usermod", pampw->pw_name, &conv, &pamh); } if (retval == PAM_SUCCESS) { retval = pam_authenticate (pamh, 0); if (retval != PAM_SUCCESS) { pam_end (pamh, retval); } } if (retval == PAM_SUCCESS) { retval = pam_acct_mgmt (pamh, 0); if (retval != PAM_SUCCESS) { pam_end (pamh, retval); } } if (retval != PAM_SUCCESS) { fprintf (stderr, _("%s: PAM authentication failed\n"), Prog); exit (1); } #endif /* USE_PAM */ /* * Do the hard stuff - open the files, change the user entries, * change the home directory, then close and update the files. */ open_files (); usr_update (); nscd_flush_cache ("passwd"); nscd_flush_cache ("group"); close_files (); if (Gflg || lflg) grp_err = grp_update (); if (mflg) move_home (); #ifndef NO_MOVE_MAILBOX if (lflg || uflg) move_mailbox (); #endif if (uflg) { update_files (); /* * Change the UID on all of the files owned by `user_id' to * `user_newid' in the user's home directory. */ chown_tree (dflg ? user_newhome : user_home, user_id, user_newid, user_gid, gflg ? user_newgid : user_gid); } if (grp_err) exit (E_GRP_UPDATE); #ifdef USE_PAM if (retval == PAM_SUCCESS) pam_end (pamh, PAM_SUCCESS); #endif /* USE_PAM */ exit (E_SUCCESS); /* NOT REACHED */ }
int remove_tree (const char *root) { char new_name[1024]; int err = 0; struct DIRECT *ent; struct stat sb; DIR *dir; /* * Make certain the directory exists. */ if (access (root, F_OK) != 0) return -1; /* * Open the source directory and read each entry. Every file * entry in the directory is copied with the UID and GID set * to the provided values. As an added security feature only * regular files (and directories ...) are copied, and no file * is made set-ID. */ dir = opendir (root); while ((ent = readdir (dir))) { /* * Skip the "." and ".." entries */ if (strcmp (ent->d_name, ".") == 0 || strcmp (ent->d_name, "..") == 0) continue; /* * Make the filename for the current entry. */ if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) { err++; break; } snprintf (new_name, sizeof new_name, "%s/%s", root, ent->d_name); if (LSTAT (new_name, &sb) == -1) continue; if (S_ISDIR (sb.st_mode)) { /* * Recursively delete this directory. */ if (remove_tree (new_name)) { err++; break; } if (rmdir (new_name)) { err++; break; } continue; } unlink (new_name); } closedir (dir); return err ? -1 : 0; }
void remove_tree(Node* u) { if(u == NULL) return; remove_tree(u->left); remove_tree(u->right); free(u); }
int main(int argc, char **argv) { struct passwd *pwd; int arg; int errors = 0; /* * Get my name so that I can use it to report errors. */ Prog = Basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH); #ifdef SHADOWPWD is_shadow_pwd = spw_file_present(); #endif #ifdef SHADOWGRP is_shadow_grp = sgr_file_present(); #endif /* * The open routines for the DBM files don't use read-write * as the mode, so we have to clue them in. */ #ifdef NDBM pw_dbm_mode = O_RDWR; #ifdef SHADOWPWD sp_dbm_mode = O_RDWR; #endif gr_dbm_mode = O_RDWR; #ifdef SHADOWGRP sg_dbm_mode = O_RDWR; #endif #endif while ((arg = getopt (argc, argv, "fr")) != EOF) { switch (arg) { case 'f': /* force remove even if not owned by user */ fflg++; break; case 'r': /* remove home dir and mailbox */ rflg++; break; default: usage(); } } if (optind + 1 != argc) usage (); /* * Start with a quick check to see if the user exists. */ user_name = argv[argc - 1]; if (! (pwd = getpwnam (user_name))) { fprintf(stderr, _("%s: user %s does not exist\n"), Prog, user_name); exit(E_NOTFOUND); } #ifdef USE_NIS /* * Now make sure it isn't an NIS user. */ if (__ispwNIS ()) { char *nis_domain; char *nis_master; fprintf(stderr, _("%s: user %s is a NIS user\n"), Prog, user_name); if (! yp_get_default_domain (&nis_domain) && ! yp_master (nis_domain, "passwd.byname", &nis_master)) { fprintf(stderr, _("%s: %s is the NIS master\n"), Prog, nis_master); } exit(E_NOTFOUND); } #endif user_id = pwd->pw_uid; user_home = xstrdup(pwd->pw_dir); /* * Check to make certain the user isn't logged in. */ user_busy (user_name, user_id); /* * Do the hard stuff - open the files, create the user entries, * create the home directory, then close and update the files. */ open_files (); update_user (); update_groups (); #ifndef NO_REMOVE_MAILBOX if (rflg) remove_mailbox(); #endif if (rflg && !fflg && !is_owner(user_id, user_home)) { fprintf(stderr, _("%s: %s not owned by %s, not removing\n"), Prog, user_home, user_name); rflg = 0; errors++; } /* This may be slow, the above should be good enough. */ #ifdef EXTRA_CHECK_HOME_DIR if (rflg && !fflg) { /* * For safety, refuse to remove the home directory * if it would result in removing some other user's * home directory. Still not perfect so be careful, * but should prevent accidents if someone has /home * or / as home directory... --marekm */ setpwent(); while ((pwd = getpwent())) { if (strcmp(pwd->pw_name, user_name) == 0) continue; if (path_prefix(user_home, pwd->pw_dir)) { fprintf(stderr, _("%s: not removing directory %s (would remove home of user %s)\n"), Prog, user_home, pwd->pw_name); rflg = 0; errors++; break; } } } #endif if (rflg) { if (remove_tree(user_home) || rmdir(user_home)) { fprintf(stderr, _("%s: error removing directory %s\n"), Prog, user_home); errors++; } } /* * Cancel any crontabs or at jobs. Have to do this before we * remove the entry from /etc/passwd. */ user_cancel(user_name); close_files (); exit(errors ? E_HOMEDIR : E_SUCCESS); /*NOTREACHED*/ }
void remove_text(text_t *text) { remove_tree(text->searchtree); free(text); }
int alphaBeta(vertex Node,int alpha, int beta,int player,int depth,int maxdepth,linked_list (*create_children)(int *gameMatrix, int player,int *error),int* error){ int aboveAlpha=alpha,aboveBeta=beta; int temp,childError; vertex child; element run; linked_list new_children; /* end-cases, return a score for some leaf */ if (depth>=maxdepth || Node->edges->head==NULL){ temp= Node->score; if(depth>1){ remove_tree(Node,0,0); } *error=0; return temp; } if (player==ENUM_PLAYER_1){ /* for every node */ for (run = Node->edges->head;run != NULL; run = run->next){ child=run->node; if (depth<maxdepth-1){ int create_childrenError=0; /*create a new level of children*/ new_children=create_children(child->game_state, player*-1,&create_childrenError); if(create_childrenError==-1){ printf("ERROR: can't create children\n"); *error=-1; return 0; } child->edges=new_children; } /* continue this process on the next level */ temp=alphaBeta(child,alpha,beta,player*-1,depth+1,maxdepth,create_children,&childError); if (childError==-1){ *error=-1; return 0; } /* we now have a score from the subtreee*/ if(aboveAlpha < temp){ aboveAlpha=temp; } /* perfom pruning on this level */ if (aboveBeta<=aboveAlpha){ for ( run = run->next;run != NULL; run = run->next){ child=run->node; if(depth>0){ remove_tree(child,0,0); } } break; } } /* taking max */ Node->score=aboveAlpha; if(depth>1){ remove_tree(Node,0,0); } *error=0; /*return some score*/ return aboveAlpha; } /* perform the same process with roles reversed */ else { for (run = Node->edges->head;run != NULL; run = run->next){ child=run->node; if (depth<maxdepth-1){ int create_childrenError=0; new_children=create_children(child->game_state, player*-1,&create_childrenError); // add children if(create_childrenError==-1){ printf("ERROR: can't create children\n"); *error=-1; return 0; } child->edges=new_children; } temp=alphaBeta(child,alpha,beta,player*-1,depth+1,maxdepth,create_children,&childError); if (childError==-1){ *error=-1; return 0; } if(aboveBeta > temp){ aboveBeta=temp; } if (aboveBeta<=aboveAlpha){ for ( run = run->next;run != NULL; run = run->next){ child=run->node; if(depth>0){ remove_tree(child,0,0); } } break; } } Node->score=aboveBeta; if(depth>1){ remove_tree(Node,0,0); } *error=0; return aboveBeta; } }
/* * main - userdel command */ int main (int argc, char **argv) { int errors = 0; /* Error in the removal of the home directory */ #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM pam_handle_t *pamh = NULL; int retval; #endif /* USE_PAM */ #endif /* ACCT_TOOLS_SETUID */ /* * Get my name so that I can use it to report errors. */ Prog = Basename (argv[0]); (void) setlocale (LC_ALL, ""); (void) bindtextdomain (PACKAGE, LOCALEDIR); (void) textdomain (PACKAGE); process_root_flag ("-R", argc, argv); OPENLOG ("userdel"); #ifdef WITH_AUDIT audit_help_open (); #endif /* WITH_AUDIT */ { /* * Parse the command line options. */ int c; static struct option long_options[] = { {"force", no_argument, NULL, 'f'}, {"help", no_argument, NULL, 'h'}, {"remove", no_argument, NULL, 'r'}, {"root", required_argument, NULL, 'R'}, #ifdef WITH_SELINUX {"selinux-user", no_argument, NULL, 'Z'}, #endif /* WITH_SELINUX */ {NULL, 0, NULL, '\0'} }; while ((c = getopt_long (argc, argv, #ifdef WITH_SELINUX "fhrR:Z", #else /* !WITH_SELINUX */ "fhrR:", #endif /* !WITH_SELINUX */ long_options, NULL)) != -1) { switch (c) { case 'f': /* force remove even if not owned by user */ fflg = true; break; case 'h': usage (E_SUCCESS); break; case 'r': /* remove home dir and mailbox */ rflg = true; break; case 'R': /* no-op, handled in process_root_flag () */ break; #ifdef WITH_SELINUX case 'Z': if (is_selinux_enabled () > 0) { Zflg = true; } else { fprintf (stderr, _("%s: -Z requires SELinux enabled kernel\n"), Prog); exit (E_BAD_ARG); } break; #endif /* WITH_SELINUX */ default: usage (E_USAGE); } } } if ((optind + 1) != argc) { usage (E_USAGE); } #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM { struct passwd *pampw; pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */ if (pampw == NULL) { fprintf (stderr, _("%s: Cannot determine your user name.\n"), Prog); exit (E_PW_UPDATE); } retval = pam_start ("userdel", pampw->pw_name, &conv, &pamh); } if (PAM_SUCCESS == retval) { retval = pam_authenticate (pamh, 0); } if (PAM_SUCCESS == retval) { retval = pam_acct_mgmt (pamh, 0); } if (PAM_SUCCESS != retval) { fprintf (stderr, _("%s: PAM: %s\n"), Prog, pam_strerror (pamh, retval)); SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval))); if (NULL != pamh) { (void) pam_end (pamh, retval); } exit (E_PW_UPDATE); } (void) pam_end (pamh, retval); #endif /* USE_PAM */ #endif /* ACCT_TOOLS_SETUID */ is_shadow_pwd = spw_file_present (); #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif /* SHADOWGRP */ #ifdef ENABLE_SUBIDS is_sub_uid = sub_uid_file_present (); is_sub_gid = sub_gid_file_present (); #endif /* ENABLE_SUBIDS */ /* * Start with a quick check to see if the user exists. */ user_name = argv[argc - 1]; { struct passwd *pwd; pwd = getpwnam (user_name); /* local, no need for xgetpwnam */ if (NULL == pwd) { fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, "deleting user not found", user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ exit (E_NOTFOUND); } user_id = pwd->pw_uid; user_gid = pwd->pw_gid; user_home = xstrdup (pwd->pw_dir); } #ifdef WITH_TCB if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) { exit (E_NOTFOUND); } #endif /* WITH_TCB */ #ifdef USE_NIS /* * Now make sure it isn't an NIS user. */ if (__ispwNIS ()) { char *nis_domain; char *nis_master; fprintf (stderr, _("%s: user %s is a NIS user\n"), Prog, user_name); if ( !yp_get_default_domain (&nis_domain) && !yp_master (nis_domain, "passwd.byname", &nis_master)) { fprintf (stderr, _("%s: %s is the NIS master\n"), Prog, nis_master); } exit (E_NOTFOUND); } #endif /* USE_NIS */ /* * Check to make certain the user isn't logged in. * Note: This is a best effort basis. The user may log in between, * a cron job may be started on her behalf, etc. */ if (user_busy (user_name, user_id) != 0) { if (!fflg) { #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, "deleting user logged in", user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ exit (E_USER_BUSY); } } /* * Do the hard stuff - open the files, create the user entries, * create the home directory, then close and update the files. */ open_files (); update_user (); update_groups (); if (rflg) { errors += remove_mailbox (); } if (rflg) { int home_owned = is_owner (user_id, user_home); if (-1 == home_owned) { fprintf (stderr, _("%s: %s home directory (%s) not found\n"), Prog, user_name, user_home); rflg = 0; } else if ((0 == home_owned) && !fflg) { fprintf (stderr, _("%s: %s not owned by %s, not removing\n"), Prog, user_home, user_name); rflg = 0; errors++; /* continue */ } } #ifdef EXTRA_CHECK_HOME_DIR /* This may be slow, the above should be good enough. */ if (rflg && !fflg) { struct passwd *pwd; /* * For safety, refuse to remove the home directory if it * would result in removing some other user's home * directory. Still not perfect so be careful, but should * prevent accidents if someone has /home or / as home * directory... --marekm */ setpwent (); while ((pwd = getpwent ())) { if (strcmp (pwd->pw_name, user_name) == 0) { continue; } if (path_prefix (user_home, pwd->pw_dir)) { fprintf (stderr, _("%s: not removing directory %s (would remove home of user %s)\n"), Prog, user_home, pwd->pw_name); rflg = false; errors++; /* continue */ break; } } endpwent (); } #endif /* EXTRA_CHECK_HOME_DIR */ if (rflg) { if (remove_tree (user_home, true) != 0) { fprintf (stderr, _("%s: error removing directory %s\n"), Prog, user_home); errors++; /* continue */ } #ifdef WITH_AUDIT else { audit_logger (AUDIT_DEL_USER, Prog, "deleting home directory", user_name, (unsigned int) user_id, SHADOW_AUDIT_SUCCESS); } #endif /* WITH_AUDIT */ } #ifdef WITH_AUDIT if (0 != errors) { audit_logger (AUDIT_DEL_USER, Prog, "deleting home directory", user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); } #endif /* WITH_AUDIT */ #ifdef WITH_SELINUX if (Zflg) { if (del_seuser (user_name) != 0) { fprintf (stderr, _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), Prog, user_name); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, "removing SELinux user mapping", user_name, (unsigned int) user_id, SHADOW_AUDIT_FAILURE); #endif /* WITH_AUDIT */ fail_exit (E_SE_UPDATE); } } #endif /* WITH_SELINUX */ /* * Cancel any crontabs or at jobs. Have to do this before we remove * the entry from /etc/passwd. */ user_cancel (user_name); close_files (); #ifdef WITH_TCB errors += remove_tcbdir (user_name, user_id); #endif /* WITH_TCB */ nscd_flush_cache ("passwd"); nscd_flush_cache ("group"); return ((0 != errors) ? E_HOMEDIR : E_SUCCESS); }