X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/6d658acdb5f61932718109ed8f339604b778ab80..2fc1e207eccd68aee093ed29dae719e77bac17dd:/chpass.tproj/chpass.c diff --git a/chpass.tproj/chpass.c b/chpass.tproj/chpass.c index 96b3d80..be23cf9 100644 --- a/chpass.tproj/chpass.c +++ b/chpass.tproj/chpass.c @@ -3,22 +3,21 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 1.0 (the 'License'). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." * * @APPLE_LICENSE_HEADER_END@ */ @@ -83,10 +82,18 @@ static char copyright[] = #include "chpass.h" #include "pathnames.h" +#ifdef DIRECTORY_SERVICE +#include "directory_service.h" + +#define PWSETFIELD(field, in, out) if(in->field) out.field = strdup(in->field) +#endif /* DIRECTORY_SERVICE */ char *progname = "chpass"; char *tempname; uid_t uid; +#ifdef DIRECTORY_SERVICE +int dswhere; +#endif /* DIRECTORY_SERVICE */ void baduser __P((void)); void usage __P((void)); @@ -100,6 +107,10 @@ main(argc, argv) struct passwd *pw, lpw; int ch, pfd, tfd; char *arg; +#ifdef DIRECTORY_SERVICE + struct passwd pworig; + char *task_argv[3] = { NULL }; +#endif /* DIRECTORY_SERVICE */ op = EDITENTRY; while ((ch = getopt(argc, argv, "a:s:")) != EOF) @@ -122,6 +133,9 @@ main(argc, argv) uid = getuid(); if (op == EDITENTRY || op == NEWSH) +#ifdef DIRECTORY_SERVICE + { +#endif /* DIRECTORY_SERVICE */ switch(argc) { case 0: if (!(pw = getpwuid(uid))) @@ -130,13 +144,53 @@ main(argc, argv) case 1: if (!(pw = getpwnam(*argv))) errx(1, "unknown user: %s", *argv); +#ifndef DIRECTORY_SERVICE if (uid && uid != pw->pw_uid) baduser(); +#endif /* DIRECTORY_SERVICE */ break; default: usage(); } +#ifdef DIRECTORY_SERVICE + if ((dswhere = wherepwent(pw->pw_name)) < 0) { + if(dswhere > E_NOTFOUND) + errc(1, dswhere, "wherepwent"); + else + errx(1, "wherepwent returned %d", dswhere); + } + switch(dswhere) { + case WHERE_REMOTENI: + errx(1, +"Can't change info for user \"%s\", which resides in the\n" +"netinfo domain \"%s\"", + pw->pw_name, DSPath); + case WHERE_DS: + errx(1, +"Can't change info for user \"%s\", which resides in the\n" +"Directory Service path \"%s\"", + pw->pw_name, DSPath); + case WHERE_NIS: + errx(1, +"Can't change info for user \"%s\", which resides in NIS", + pw->pw_name); + case WHERE_LOCALNI: + pworig = *pw; + PWSETFIELD(pw_name, pw, pworig); + PWSETFIELD(pw_passwd, pw, pworig); + PWSETFIELD(pw_class, pw, pworig); + PWSETFIELD(pw_gecos, pw, pworig); + PWSETFIELD(pw_dir, pw, pworig); + PWSETFIELD(pw_shell, pw, pworig); + /* drop through */ + default: + if (uid && uid != pw->pw_uid) + baduser(); + } + } +#endif /* DIRECTORY_SERVICE */ + if (op == NEWSH) { /* protect p_shell -- it thinks NULL is /bin/sh */ if (!arg[0]) @@ -146,10 +200,14 @@ main(argc, argv) } if (op == LOADENTRY) { +#ifdef DIRECTORY_SERVICE + warnx("-a is only supported for %s", MasterPasswd); + dswhere = WHERE_FILES; +#endif /* DIRECTORY_SERVICE */ if (uid) baduser(); pw = &lpw; - if (!pw_scan(arg, pw)) + if (!pw_scan(arg, pw, NULL)) exit(1); } @@ -179,23 +237,87 @@ main(argc, argv) * The exit closes the master passwd fp/fd. */ pw_init(); - pfd = pw_lock(); +#ifdef DIRECTORY_SERVICE + if (dswhere == WHERE_FILES) +#endif /* DIRECTORY_SERVICE */ + pfd = pw_lock(); tfd = pw_tmp(); if (op == EDITENTRY) { +#ifdef DIRECTORY_SERVICE + setrestricted(dswhere, pw); +#endif /* DIRECTORY_SERVICE */ display(tfd, pw); edit(pw); (void)unlink(tempname); - tfd = pw_tmp(); +#ifdef DIRECTORY_SERVICE + if (dswhere == WHERE_FILES) +#endif /* DIRECTORY_SERVICE */ + tfd = pw_tmp(); } - pw_copy(pfd, tfd, pw); +#ifdef DIRECTORY_SERVICE + switch (dswhere) { + case WHERE_LOCALNI: + update_local_ni(&pworig, pw); + break; + case WHERE_FILES: +#endif /* DIRECTORY_SERVICE */ + pw_copy(pfd, tfd, pw); - if (!pw_mkdb()) - pw_error((char *)NULL, 0, 1); + if (pw_mkdb() != 0) + pw_error((char *)NULL, 0, 1); +#ifdef DIRECTORY_SERVICE + } + task_argv[0] = "/usr/sbin/lookupd"; + task_argv[1] = "-flushcache"; + task_argv[2] = NULL; + LaunchTaskWithPipes( task_argv[0], task_argv, NULL, NULL ); +#endif /* DIRECTORY_SERVICE */ exit(0); } +#ifdef DIRECTORY_SERVICE +// read from 0 +int LaunchTaskWithPipes(const char *path, char *const argv[], int *outPipe0, int *outPipe1) +{ + int outputPipe[2]; + pid_t pid; + + if (outPipe0 != NULL) + pipe(outputPipe); + + pid = fork(); + if (pid == -1) + return -1; + + /* Handle the child */ + if (pid == 0) + { + int result = -1; + + if (outPipe0 != NULL) + dup2(outputPipe[1], fileno(stdout)); + + result = execv(path, argv); + if (result == -1) { + _exit(1); + } + + /* This should never be reached */ + _exit(1); + } + + /* Now the parent */ + if ( outPipe0 != NULL ) + *outPipe0 = outputPipe[0]; + if ( outPipe1 != NULL ) + *outPipe1 = outputPipe[1]; + + return 0; +} +#endif /* DIRECTORY_SERVICE */ + void baduser() {