1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2024 OmniOS Community Edition (OmniOSce) Association. 25 */ 26 27 #include <errno.h> 28 #include <sys/types.h> 29 #include <sys/types.h> 30 #include <nsswitch.h> 31 #include <stdlib.h> 32 #include <stdio.h> 33 #include <string.h> 34 #include <syslog.h> 35 36 #include "passwdutil.h" 37 38 int 39 __set_authtoken_attr(const char *name, const char *oldpw, pwu_repository_t *rep, 40 attrlist *items, int *updated_reps) 41 { 42 attrlist *p; 43 int repositories; 44 int i; 45 void *buf; /* workspace for repository specific funcs */ 46 int err = PWU_NOT_FOUND; 47 int rep_success = REP_NOREP; /* first successfull update */ 48 int updated = REP_NOREP; /* (bitmask) all updates */ 49 50 /* Can't set name uid or flag */ 51 for (p = items; p != NULL; p = p->next) { 52 switch (p->type) { 53 case ATTR_NAME: 54 case ATTR_UID: 55 case ATTR_FLAG: 56 return (EINVAL); 57 } 58 } 59 60 repositories = get_ns(rep, PWU_WRITE); 61 62 if (repositories == 0) 63 return (PWU_SYSTEM_ERROR); 64 65 /* 66 * updating requires that either 67 * - PAM_REPOSITORY is set: we know what to update 68 * - PAM_REPOSITORY is not set, but we recognize the nsswitch.conf 69 * passwd: entry 70 */ 71 if (repositories == REP_ERANGE || repositories == REP_NSS) 72 return (PWU_REPOSITORY_ERROR); 73 74 /* 75 * Loop over selected repositories to update 76 * We should update the remote repositories first, FILES last. 77 */ 78 for (i = REP_LAST; i; i >>= 1) { 79 if (repositories & i) { 80 buf = NULL; 81 82 if (rops[i]->lock && (err = rops[i]->lock())) { 83 return (err); 84 } 85 86 if (rops[i]->getpwnam) { 87 err = rops[i]->getpwnam(name, items, rep, &buf); 88 } 89 90 if ((err == PWU_SUCCESS) && rops[i]->update) 91 err = rops[i]->update(items, rep, buf); 92 93 if ((err == PWU_SUCCESS) && rops[i]->putpwnam) 94 err = rops[i]->putpwnam(name, oldpw, rep, buf); 95 96 if (rops[i]->unlock) 97 (void) rops[i]->unlock(); 98 99 if (buf) { 100 (void) free(buf); 101 buf = NULL; 102 } 103 if (err == PWU_SUCCESS) { 104 rep_success = i; /* this rep succeeded */ 105 updated |= i; 106 } else if (err != PWU_SUCCESS && err != PWU_NOT_FOUND) { 107 break; 108 } 109 } 110 } 111 112 if (buf) 113 free(buf); 114 115 if (updated_reps) 116 *updated_reps = (updated != REP_NOREP) ? updated : i; 117 118 /* 119 * err contains either 120 * PWU_SUCCESS : everyting went OK 121 * PWU_NOT_FOUND : none of the repositories contained the user 122 * error-code : the specific error that occurred 123 */ 124 if (rep_success != REP_NOREP) { 125 return (PWU_SUCCESS); 126 } else { 127 return (err); 128 } 129 } 130