📄 usermod.c
字号:
utf8_to_locale (new_groups[new_groupscnt])); /* return E_BAD_ARG; */ } else { new_groupscnt++; if (new_groupscnt > j) abort (); } } } arg = cp; } while (arg); if (errors) { /* This is more a guess than something else. */ if (files_etc_dir) return E_NOTFOUND; else return E_BAD_ARG; } } /* Create list of groups, to which we should add this account. -R option. */ /* XXX merge with new_groups_arg above. */ if (remove_groups_arg) { char *arg = remove_groups_arg; unsigned int errors = 0, i, j; j = 1; for (i = 0; i < strlen (arg); i++) if (arg[i] == ',') ++j; del_groups = malloc (sizeof (char *) * j); del_groupscnt = 0; do { char *cp = strchr (arg, ','); if (cp) *cp++ = '\0'; if (arg && *arg) { gid_t gid; if (convert_grpopt_to_name (arg, &del_groups[del_groupscnt], &gid, use_service) != 0) ++errors; else { del_groupscnt++; if (del_groupscnt > j) abort (); } } arg = cp; } while (arg); if (errors) { /* This is more a guess than something else. */ if (files_etc_dir) return E_NOTFOUND; else return E_BAD_ARG; } } /* Check if user is logged in. */ if ((new_login || know_uid || new_home) && is_logged_in (modify_account)) { sec_log (program, MSG_ACCOUNT_IN_USE, modify_account, pw_data->pw.pw_uid, getuid ()); fprintf (stderr, _("%s: Account `%s' is currently in use.\n"), program, utf8_to_locale (modify_account)); return E_USER_BUSY; } /* After this, we can start modifying the existing account. */ if (know_uid != NULL && !non_unique) { if (getpwuid (new_uid) != NULL || (have_extrapath && files_getpwuid (new_uid) != NULL)) { sec_log (program, MSG_UID_NOT_UNIQUE, new_uid, getuid ()); fprintf (stderr, _("%s: UID %u is not unique.\n"), program, new_uid); return E_UID_IN_USE; } } /* If account should be renamed, check that the new name is valid and does not already exist. */ if (new_login) { if (check_name (new_login) != 0) { sec_log (program, MSG_USER_NAME_INVALID, new_login, getuid ()); fprintf (stderr, _("%s: Invalid account name `%s'.\n"), program, utf8_to_locale (new_login)); return E_BAD_ARG; } else { if (getpwnam (new_login) != NULL || (have_extrapath && files_getpwnam (new_login) != NULL)) { sec_log (program, MSG_USER_ALREADY_EXISTS, new_login, getuid ()); fprintf (stderr, _("%s: Account `%s' already exists.\n"), program, utf8_to_locale (new_login)); return E_NAME_IN_USE; } } } /* Lock passwd file, so that a concurrent usermod process will not add the user a second time or a second user with the same uid. */ if ((use_service == NULL || strcmp (use_service, "files") == 0) && lock_database () != 0) { sec_log (program, MSG_PASSWD_FILE_ALREADY_LOCKED); fputs (_("Cannot lock password file: already locked.\n"), stderr); return E_PWDBUSY; } else if (new_login || new_password || know_uid || new_group || new_comment || new_home || new_shell || know_inactive || know_expire) { /* Only change passwd/shadow file if there are really changes. */ pw_data->todo = DO_MODIFY; if (new_login) pw_data->new_name = strdup (new_login); if (know_uid) { pw_data->have_new_uid = 1; pw_data->new_uid = new_uid; } if (new_group) { pw_data->have_new_gid = 1; pw_data->new_gid = new_gid; } if (new_comment) pw_data->new_gecos = strdup (new_comment); if (new_home) pw_data->new_home = strdup (new_home); if (new_shell) pw_data->new_shell = strdup (new_shell); if (know_inactive || know_expire) { if (pw_data->use_shadow) { pw_data->spn = pw_data->sp; pw_data->sp_changed = 1; if (know_inactive) pw_data->spn.sp_inact = new_inactive; if (know_expire) pw_data->spn.sp_expire = new_expire; } else { fprintf (stderr, _("%s: Shadow passwords required for -e and -f.\n"), program); return E_NO_SHADOW; } } if (new_password) { pw_data->newpassword = strdup (new_password); if (pw_data->use_shadow) { pw_data->spn.sp_lstchg = time ((time_t *) 0) / SCALE; pw_data->sp_changed = 1; } }#ifdef USE_LDAP if (pw_data->service == S_LDAP) { if (binddn == NULL) { binddn = get_caller_dn (); if (binddn == NULL) { fprintf (stderr, _("%s: Cannot modify user in LDAP database without DN.\n"), program); } else pw_data->binddn = strdup (binddn); } else pw_data->binddn = strdup (binddn); if (pw_data->oldclearpwd == NULL) { char *cp = get_ldap_password (pw_data->binddn); if (cp) pw_data->oldclearpwd = strdup (cp); else { fprintf (stderr, _("%s: User not modified in LDAP database.\n"), program); return E_FAILURE; } } }#endif if (write_user_data (pw_data, 1) != 0) { sec_log (program, MSG_ERROR_MODIFYING_USER, pw_data->pw.pw_name, pw_data->pw.pw_uid, getuid()) return E_FAILURE; } else { if (new_login) sec_log (program, MSG_USER_NAME_CHANGED, pw_data->new_name, pw_data->pw.pw_name, pw_data->pw.pw_uid, getuid ()); if (new_password) sec_log (program, MSG_PASSWORD_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, getuid ()); if (pw_data->new_uid) sec_log (program, MSG_USER_ID_CHANGED, pw_data->pw.pw_name, pw_data->new_uid, pw_data->pw.pw_uid, getuid ()); if (new_comment) sec_log (program, MSG_GECOS_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, pw_data->new_gecos, pw_data->pw.pw_gecos, getuid ()); if (new_group) sec_log (program, MSG_PRIMARY_GROUP_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, pw_data->new_gid, pw_data->pw.pw_gid , getuid ()); if (new_home) sec_log (program, MSG_HOME_DIR_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, pw_data->new_home, pw_data->pw.pw_dir, getuid ()); if (new_shell) sec_log (program, MSG_SHELL_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, pw_data->new_shell, pw_data->pw.pw_shell, getuid ()); if (know_inactive) sec_log (program, MSG_INACTIVE_DAYS_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, pw_data->spn.sp_inact, pw_data->sp.sp_inact, getuid ()); if (know_expire) sec_log (program, MSG_EXPIRE_DATE_CHANGED, pw_data->pw.pw_name, pw_data->pw.pw_uid, date2str(DAY*pw_data->spn.sp_expire), date2str(DAY*pw_data->sp.sp_expire), getuid ()); }#ifdef HAVE_NSCD_FLUSH_CACHE /* flush NSCD cache, else later calls could get obsolete data. */ nscd_flush_cache ("passwd");#endif } /* Change the login name in group entries, too. But only, if we don't need to remove them all later. */ if (new_login && (new_groups_arg == NULL || new_groupscnt == 0)) { if (rename_in_secondary_groups (pw_data, have_extrapath) != 0) retval = E_FAILURE; /* Make sure, written group changes will be active now. */#ifdef HAVE_NSCD_FLUSH_CACHE nscd_flush_cache ("group");#endif } /* Now we need to change the group file (-G/-A option). */ if (new_groups_arg || add_groups_arg) { unsigned int i; int ret; if (new_groups_arg) { /* Remove user from all groups. */ if (new_login) ret = remove_from_secondary_groups (pw_data, have_extrapath, new_login); else ret = remove_from_secondary_groups (pw_data, have_extrapath, pw_data->pw.pw_name); if (ret != 0) retval = ret; } for (i = 0; i < new_groupscnt; i++) { group_t *gr_data = find_group_data (new_groups[i], 0, use_service); if (gr_data == NULL || gr_data->service == S_NONE) { if (use_service == NULL) fprintf (stderr, _("%s: ERROR: Cannot find group `%s' anymore!\n"), program, utf8_to_locale (new_groups[i])); else fprintf (stderr, _("%s: Cannot find group `%s' in service `%s', ignored.\n"), program, utf8_to_locale (new_groups[i]), use_service); retval = E_NOTFOUND; } else { gr_data->todo = DO_MODIFY;#ifdef USE_LDAP if (gr_data->service == S_LDAP) { if (binddn == NULL) { binddn = get_caller_dn (); if (binddn == NULL) { fprintf (stderr, _("%s: Cannot add user to groups stored in LDAP database without DN.\n"), program); } } if (binddn == NULL) { fprintf (stderr, _("%s: User not added to LDAP group `%s'.\n"), program, utf8_to_locale (gr_data->gr.gr_name)); free_group_t (gr_data); retval = E_GRP_UPDATE; continue; } gr_data->binddn = strdup (binddn); if (pw_data->oldclearpwd == NULL) { char *cp = get_ldap_password (binddn); if (cp) pw_data->oldclearpwd = strdup (cp); else { fprintf (stderr, _("%s: User not added to LDAP group `%s'.\n"), program, utf8_to_locale (gr_data->gr.gr_name)); free_group_t (gr_data); retval = E_GRP_UPDATE; continue; } } if (pw_data->oldclearpwd) gr_data->oldclearpwd = strdup (pw_data->oldclearpwd); }#endif gr_data->new_gr_mem = add_gr_mem (modify_account, gr_data->gr.gr_mem); if (write_group_data (gr_data, 1) != 0) { fprintf (stderr, _("%s: User not added to LDAP group `%s'.\n"), program, utf8_to_locale (gr_data->gr.gr_name)); retval = E_GRP_UPDATE; } else { sec_log (program, MSG_USER_ADDED_TO_GROUP, pw_data->pw.pw_name, gr_data->gr.gr_name, gr_data->gr.gr_gid, getuid ()); } /* Make sure, written group changes will be active now. */#ifdef HAVE_NSCD_FLUSH_CACHE nscd_flush_cache ("group");#endif } free_group_t (gr_data); } } /* Now we need to change the group file (-R option). */ /* XXX merge with above. */ if (remove_groups_arg) { unsigned int i; for (i = 0; i < del_groupscnt; i++) { group_t *gr_data = find_group_data (del_groups[i], 0, use_service); if (gr_data == NULL || gr_data->service == S_NONE) { if (use_service == NULL) fprintf (stderr, _("%s: ERROR: cannot find group `%s' anymore!\n"), program, utf8_to_locale (del_groups[i])); else fprintf (stderr, _("%s: Cannot find group `%s' in service `%s', ignored.\n"), program, utf8_to_locale (del_groups[i]), use_service); retval = E_NOTFOUND; } else { gr_data->todo = DO_MODIFY;#ifdef USE_LDAP if (gr_data->service == S_LDAP) { if (binddn == NULL) { binddn = get_caller_dn (); if (binddn == NULL) { fprintf (stderr, _("%s: Cannot remove user from groups stored in LDAP database without DN.\n"), program); } } if (binddn == NULL) { fprintf (stderr, _("%s: User not removed from LDAP group `%s'.\n"), program, utf8_to_locale (gr_data->gr.gr_name)); free_group_t (gr_data); retval = E_GRP_UPDATE; continue; } gr_data->binddn = strdup (binddn); if (pw_data->oldclearpwd == NULL) { char *cp = get_ldap_password (binddn); if (cp) pw_data->oldclearpwd = strdup (cp); else { fprintf (stderr, _("%s: User not removed from LDAP group `%s'.\n"), program, utf8_to_locale (gr_data->gr.gr_name)); free_group_t (gr_data); retval = E_GRP_UPDATE; continue; } } if (pw_data->oldclearpwd) gr_data->oldclearpwd = strdup (pw_data->oldclearpwd); }#endif gr_data->new_gr_mem = remove_gr_mem (modify_account, gr_data->gr.gr_mem); if (write_group_data (gr_data, 1) != 0) { fprintf (stderr, _("%s: User not removed from LDAP group `%s'.\n"), program, utf8_to_locale (gr_data->gr.gr_name)); retval = E_GRP_UPDATE; } else { sec_log (program, MSG_USER_ADDED_TO_GROUP, pw_data->pw.pw_name, gr_data->gr.gr_name, gr_data->gr.gr_gid, getuid ()); } /* Make sure, written group changes will be active now. */#ifdef HAVE_NSCD_FLUSH_CACHE nscd_flush_cache ("group");#endif } free_group_t (gr_data); } } if (move_homedir) if (move_home_directory (old_home, new_home) != 0) retval = E_FAILURE; /* If UID has changed, change the UID of the homedirectory, too. */ if (know_uid) { int fd; int ret; char *home = new_home ? new_home : old_home; /* Only change the UID of the home directory, if it exist. Else ignore it. */ if (access (home, F_OK) == 0) { /* If know_uid is set, change UID on filesystem of file in the home directory. */ ret = chown_dir_rec (home, pw_data->pw.pw_uid, new_uid, pw_data->pw.pw_gid, new_group ? new_gid : pw_data->pw.pw_gid); if (ret != 0) retval = E_FAILURE; } /* Relocate the "lastlog/faillog" entries for the user. */ if ((fd = open ("/var/log/faillog", O_RDWR)) >= 0) { struct faillog fl; if (lseek (fd, (off_t) sizeof (fl) * pw_data->pw.pw_uid, SEEK_SET) == (off_t) -1) { fprintf (stderr, _("%s: Error: Cannot copy faillog entry: %s\n"), program, strerror (errno)); retval = E_FAILURE; } else if (read (fd, &fl, sizeof (fl)) == sizeof (fl)) { if ((lseek (fd, (off_t) sizeof (fl) * new_uid, SEEK_SET) == (off_t) -1) || (write (fd, &fl, sizeof (fl)) == -1)) { fprintf (stderr, _("%s: Error: Cannot copy faillog entry: %s\n"), program, strerror (errno)); retval = E_FAILURE; } } close (fd); } if ((fd = open (_PATH_LASTLOG, O_RDWR, 0)) >= 0) { struct lastlog ll; if (lseek (fd, (off_t) sizeof (ll) * pw_data->pw.pw_uid, SEEK_SET) == (off_t) -1) { fprintf (stderr, _("%s: Error: Cannot copy lastlog entry: %s\n"), program, strerror (errno)); retval = E_FAILURE; } else if (read (fd, &ll, sizeof ll) == sizeof ll) { if ((lseek (fd, (off_t) sizeof (ll) * new_uid, SEEK_SET) == (off_t) -1) || (write (fd, &ll, sizeof (ll)) == -1)) { fprintf (stderr, _("%s: Error: Cannot copy faillog entry: %s\n"), program, strerror (errno)); retval = E_FAILURE; } } close (fd); } } if (use_service == NULL || strcmp (use_service, "files") == 0) ulckpwdf (); return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -