📄 user.c
字号:
pw->pw_name[0] == '+' || pw->pw_name[0] == '-')) { /* write the passwd entry to tmp file */ if (putpwent (&data->pw, newpf) < 0) { fprintf (stderr, _("Error while writing `%s': %m\n"), passwd_tmp); fclose (oldpf); fclose (newpf); retval = -1; goto error_passwd; } gotit = 1; } } else if (data->todo == DO_DELETE) { if (data->pw.pw_uid == pw->pw_uid && data->pw.pw_gid == pw->pw_gid && strcmp (data->pw.pw_name, pw->pw_name) == 0) { gotit = 1; continue; } } else { /* check if this is the uid we want to change. A few sanity checks added for consistency. */ if (data->pw.pw_uid == pw->pw_uid && data->pw.pw_gid == pw->pw_gid && strcmp (data->pw.pw_name, pw->pw_name) == 0 && !gotit) { if (data->newpassword && !data->use_shadow) pw->pw_passwd = data->newpassword; if (data->new_name) pw->pw_name = data->new_name; if (data->new_shell) pw->pw_shell = data->new_shell; if (data->new_gecos) pw->pw_gecos = data->new_gecos; if (data->new_home) pw->pw_dir = data->new_home; if (data->have_new_uid) pw->pw_uid = data->new_uid; if (data->have_new_gid) pw->pw_gid = data->new_gid; gotit = 1; } } /* write the passwd entry to tmp file */ if (putpwent (pw, newpf) < 0) { fprintf (stderr, _("Error while writing `%s': %m\n"), passwd_tmp); fclose (oldpf); fclose (newpf); retval = -1; goto error_passwd; } } if (data->todo == DO_CREATE && !gotit) { /* write the passwd entry to tmp file */ if (putpwent (&data->pw, newpf) < 0) { fprintf (stderr, _("Error while writing `%s': %m\n"), passwd_tmp); fclose (oldpf); fclose (newpf); retval = -1; goto error_passwd; } } else if (data->todo == DO_DELETE && !gotit) { fprintf (stderr, _("User not found (and not deleted): %s\n"), data->pw.pw_name); retval = -1; } if (fclose (oldpf) != 0) { fprintf (stderr, _("Error while closing `%s': %m\n"), passwd_orig); fclose (newpf); retval = -1; goto error_passwd; } if (fclose (newpf) != 0) { fprintf (stderr, _("Error while closing `%s': %m\n"), passwd_tmp); retval = -1; goto error_passwd; } unlink (passwd_old); if (link (passwd_orig, passwd_old) < 0) fprintf (stderr, _("Warning: cannot create backup file `%s': %m\n"), passwd_old); if (rename (passwd_tmp, passwd_orig) < 0) { fprintf (stderr, _("Error while renaming `%s': %m\n"), passwd_tmp); retval = -1; goto error_passwd; } error_passwd: unlink (passwd_tmp); } /* If we use shadow data, check if we need to change here something, too. But do this only, if there no error occured before. */ if (data->use_shadow && retval == 0 && (data->todo == DO_CREATE || data->todo == DO_CREATE_SHADOW || data->todo == DO_DELETE || data->todo == DO_DELETE_SHADOW || data->new_name || data->newpassword || data->sp_changed)) { const char *file_tmp = "/shadow.tmpXXXXXX"; char *shadow_tmp = alloca (strlen (files_etc_dir) + strlen (file_tmp) + 1); char *shadow_orig = alloca (strlen (files_etc_dir) + 8); char *shadow_old = alloca (strlen (files_etc_dir) + 12); struct stat shadow_stat; struct spwd *sp; /* shadow struct obtained from fgetspent() */ FILE *oldpf, *newpf; int gotit, newpf_fd; char *cp; cp = stpcpy (shadow_tmp, files_etc_dir); strcpy (cp, file_tmp); cp = stpcpy (shadow_orig, files_etc_dir); strcpy (cp, "/shadow"); cp = stpcpy (shadow_old, shadow_orig); strcpy (cp, ".old"); /* Open the shadow file for reading. We can't use getspent and friends here, because they go through the YP maps, too. */ if ((oldpf = fopen (shadow_orig, "r")) == NULL) { fprintf (stderr, _("Can't open `%s': %m\n"), shadow_orig); retval = -1; goto error_shadow; } if (fstat (fileno (oldpf), &shadow_stat) < 0) { fprintf (stderr, _("Can't stat `%s': %m\n"), shadow_orig); fclose (oldpf); retval = -1; goto error_shadow; }#ifdef WITH_SELINUX security_context_t prev_context; if (set_default_context (shadow_orig, &prev_context) < 0) { fclose (oldpf); retval = -1; goto error_shadow; }#endif /* Open a temp shadow file */ newpf_fd = mkstemp (shadow_tmp);#ifdef WITH_SELINUX if (restore_default_context (prev_context) < 0) { if (newpf_fd >= 0) close (newpf_fd); fclose (oldpf); retval = -1; goto error_shadow; }#endif if (newpf_fd == -1) { fprintf (stderr, _("Can't create `%s': %m\n"), shadow_orig); fclose (oldpf); retval = -1; goto error_shadow; } if (fchmod (newpf_fd, shadow_stat.st_mode) < 0) { fprintf (stderr, _("Cannot change permissions for `%s': %s\n"), shadow_tmp, strerror (errno)); fclose (oldpf); close (newpf_fd); unlink (shadow_tmp); retval = -1; goto error_shadow; } if (fchown (newpf_fd, shadow_stat.st_uid, shadow_stat.st_gid) < 0) { fprintf (stderr, _("Cannot change owner/group for `%s': %s\n"), shadow_tmp, strerror (errno)); fclose (oldpf); close (newpf_fd); unlink (shadow_tmp); retval = -1; goto error_shadow; } if (copy_xattr (shadow_orig, shadow_tmp) != 0) { fclose (oldpf); close (newpf_fd); unlink (shadow_tmp); retval = -1; goto error_shadow; } newpf = fdopen (newpf_fd, "w+"); if (newpf == NULL) { fprintf (stderr, _("Can't open `%s': %m\n"), shadow_tmp); fclose (oldpf); close (newpf_fd); unlink (shadow_tmp); retval = -1; goto error_shadow; } gotit = 0; /* Loop over all passwd entries */ while ((sp = fgetspent (oldpf)) != NULL) { if (data->todo == DO_CREATE || data->todo == DO_CREATE_SHADOW) { /* insert the new user before we find a +/- character or an old entry from a deleted user. */ if (!gotit && (sp->sp_namp[0] == '+' || sp->sp_namp[0] == '-' || strcmp (sp->sp_namp, data->sp.sp_namp) == 0)) { /* write the passwd entry to tmp file */ if (putspent (&data->sp, newpf) < 0) { fprintf (stderr, _("Error while writing `%s': %m\n"), shadow_tmp); fclose (oldpf); fclose (newpf); retval = -1; goto error_shadow; } gotit = 1; } } else if (data->todo == DO_DELETE || data->todo == DO_DELETE_SHADOW) { if (strcmp (data->pw.pw_name, sp->sp_namp) == 0) { gotit = 1; continue; } } else /* check if this is the uid we want to change. A few sanity checks added for consistency. */ if (!gotit && strcmp (data->pw.pw_name, sp->sp_namp) == 0) { if (data->newpassword) sp->sp_pwdp = data->newpassword; if (data->new_name) sp->sp_namp = data->new_name; if (data->sp_changed) { /* if they have changed, they are different. If not, they are equal, so copying them doesn't matter. */ sp->sp_max = data->spn.sp_max; sp->sp_min = data->spn.sp_min; sp->sp_warn = data->spn.sp_warn; sp->sp_inact = data->spn.sp_inact; sp->sp_lstchg = data->spn.sp_lstchg; sp->sp_expire = data->spn.sp_expire; } gotit = 1; } /* Write the entry only if we don't create a new account or if this is not a duplicate of the new user account. */ if ((data->todo != DO_CREATE && data->todo != DO_CREATE_SHADOW) || strcmp (sp->sp_namp, data->sp.sp_namp) != 0) { /* write the passwd entry to tmp file */ if (putspent (sp, newpf) < 0) { fprintf (stderr, _(" Error while writing `%s': %m\n"), shadow_tmp); fclose (oldpf); fclose (newpf); retval = -1; goto error_shadow; } } } if ((data->todo == DO_CREATE || data->todo == DO_CREATE_SHADOW) && !gotit) { /* Add the new user at the end. */ if (putspent (&data->sp, newpf) < 0) { fprintf (stderr, _("Error while writing `%s': %m\n"), shadow_tmp); fclose (oldpf); fclose (newpf); retval = -1; goto error_shadow; } } if (fclose (oldpf) != 0) { fprintf (stderr, _("Error while closing `%s': %m\n"), shadow_orig); fclose (newpf); retval = -1; goto error_shadow; } if (fclose (newpf) != 0) { fprintf (stderr, _("Error while closing `%s': %m\n"), shadow_tmp); retval = -1; goto error_shadow; } unlink (shadow_old); if (link (shadow_orig, shadow_old) < 0) fprintf (stderr, _("Warning: cannot create backup file `%s': %m\n"), shadow_old); if (rename (shadow_tmp, shadow_orig) < 0) { fprintf (stderr, _("Error while renaming `%s': %m\n"), shadow_tmp); retval = -1; goto error_shadow; } error_shadow: unlink (shadow_tmp); } /* Don't unlock if program itself helds lock. */ if (!is_locked) ulckpwdf (); } else if (data->service == S_YP) { struct yppasswd yppwd; CLIENT *clnt; char *master = getnismaster(); struct timeval TIMEOUT = {25, 0}; /* total timeout */ int error, status; /* Changing shadow information is not supported. */ if (data->sp_changed) return -1; if (master == NULL) return -1; /* Initialize password information */ memset (&yppwd, '\0', sizeof (yppwd)); yppwd.newpw.pw_passwd = data->pw.pw_passwd; yppwd.newpw.pw_name = data->pw.pw_name; yppwd.newpw.pw_uid = data->pw.pw_uid; yppwd.newpw.pw_gid = data->pw.pw_gid; if (data->new_gecos) yppwd.newpw.pw_gecos = data->new_gecos; else yppwd.newpw.pw_gecos = data->pw.pw_gecos; yppwd.newpw.pw_dir = data->pw.pw_dir; if (data->new_shell) yppwd.newpw.pw_shell = data->new_shell; else yppwd.newpw.pw_shell = data->pw.pw_shell; if (data->oldclearpwd != NULL) yppwd.oldpass = data->oldclearpwd; else yppwd.oldpass = (char *)""; clnt = clnt_create (master, YPPASSWDPROG, YPPASSWDVERS, "udp"); clnt->cl_auth = authunix_create_default (); memset (&status, '\0', sizeof (status)); error = clnt_call (clnt, YPPASSWDPROC_UPDATE, (xdrproc_t) xdr_yppasswd, (caddr_t) &yppwd, (xdrproc_t) xdr_int, (caddr_t) &status, TIMEOUT); if (error || status) { if (error) clnt_perrno (error); else fprintf (stderr, _("Error while changing the NIS data.\n")); retval = -1; } } else if (data->service == S_NISPLUS) { retval = npd_upd_pwd ("", data); if (retval != 0) { fprintf (stderr, _("Error while changing the NIS+ data.\n")); retval = -1; } }#ifdef USE_LDAP else if (data->service == S_LDAP) { ldap_session_t *session = NULL; session = create_ldap_session (LDAP_PATH_CONF); if (session == NULL) retval = -1; else { if (data->todo == DO_CREATE) retval = ldap_create_user (session, &(data->pw), &(data->sp), data->binddn, data->oldclearpwd); else if (data->todo == DO_DELETE) retval = ldap_delete_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd); else { /* XXX retval will be overwritten!!! */ if (data->new_shell) retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "loginShell", data->new_shell); if (data->new_gecos) retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "gecos", data->new_gecos); if (data->new_name) retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "uid", data->new_name); if (data->have_new_uid) { char buf[100]; snprintf (buf, sizeof (buf), "%u", data->new_uid); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "uidNumber", buf); } if (data->have_new_gid) { char buf[100]; snprintf (buf, sizeof (buf), "%u", data->new_gid); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "gidNumber", buf); } if (data->new_home) retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "homeDirectory", data->new_home); if (data->sp_changed) { char buf[200]; snprintf (buf, sizeof (buf), "%ld", data->spn.sp_min); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "shadowMin", buf); snprintf (buf, sizeof (buf),"%ld", data->spn.sp_max); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "shadowMax", buf); snprintf (buf, sizeof (buf),"%ld", data->spn.sp_warn); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "shadowWarning", buf); snprintf (buf, sizeof (buf),"%ld", data->spn.sp_inact); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "shadowInactive", buf); snprintf (buf, sizeof (buf),"%ld", data->spn.sp_lstchg); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "shadowLastChange", buf); snprintf (buf, sizeof (buf),"%ld", data->spn.sp_expire); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "shadowExpire", buf); } if (data->newpassword) { const char *cryptstr = "{crypt}"; char buffer[strlen (data->newpassword) + strlen (cryptstr) + 1]; snprintf (buffer, sizeof (buffer), "%s%s", cryptstr, data->newpassword); retval = ldap_update_user (session, data->pw.pw_name, data->binddn, data->oldclearpwd, "userPassword", buffer); } } if (retval != 0) fprintf (stderr, _("LDAP information update failed: %s\n"), ldap_err2string (retval)); close_ldap_session (session); } }#endif else { fprintf (stderr, _("Unknown service %d.\n"), data->service); retval = -1; } return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -