Esempio n. 1
0
/** 
 * 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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/**
 * 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);
    }
 }
Esempio n. 4
0
/* 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;
}
Esempio n. 5
0
/*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;
}
Esempio n. 6
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);
}
Esempio n. 7
0
/* 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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
/**
 * 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);
}
Esempio n. 10
0
File: main.c Progetto: goshng/cocoa
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;
}
Esempio n. 11
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;
}
Esempio n. 12
0
/* 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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
/*
 * 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 */
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
void remove_tree(Node* u) {
  if(u == NULL) return;
  remove_tree(u->left);
  remove_tree(u->right);
  free(u);
}
Esempio n. 17
0
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*/
}
Esempio n. 18
0
void remove_text(text_t *text)
{
	remove_tree(text->searchtree);
	free(text);
}
Esempio n. 19
0
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;
	}
}
Esempio n. 20
0
/*
 * 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);
}