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 */ 25 26 #include <errno.h> 27 #include <sys/types.h> 28 #include <sys/types.h> 29 #include <nsswitch.h> 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <syslog.h> 34 35 #include "passwdutil.h" 36 37 int 38 __set_authtoken_attr(char *name, char *oldpw, pwu_repository_t *rep, 39 attrlist *items, int *updated_reps) 40 { 41 attrlist *p; 42 int repositories; 43 int i; 44 void *buf; /* workspace for repository specific funcs */ 45 int err = PWU_NOT_FOUND; 46 int rep_success = REP_NOREP; /* first successfull update */ 47 int updated = REP_NOREP; /* (bitmask) all updates */ 48 49 /* Can't set name uid or flag */ 50 for (p = items; p != NULL; p = p->next) { 51 switch (p->type) { 52 case ATTR_NAME: 53 case ATTR_UID: 54 case ATTR_FLAG: 55 return (EINVAL); 56 } 57 } 58 59 repositories = get_ns(rep, PWU_WRITE); 60 61 if (repositories == 0) 62 return (PWU_SYSTEM_ERROR); 63 64 /* 65 * updating requires that either 66 * - PAM_REPOSITORY is set: we know what to update 67 * - PAM_REPOSITORY is not set, but we recognize the nsswitch.conf 68 * passwd: entry 69 */ 70 if (repositories == REP_ERANGE || repositories == REP_NSS) 71 return (PWU_REPOSITORY_ERROR); 72 73 /* 74 * Loop over selected repositories to update 75 * We should update the remote repositories first, FILES last. 76 */ 77 for (i = REP_LAST; i; i >>= 1) { 78 if (repositories & i) { 79 buf = NULL; 80 81 if (rops[i]->lock && (err = rops[i]->lock())) { 82 return (err); 83 } 84 85 if (rops[i]->getpwnam) { 86 err = rops[i]->getpwnam(name, items, rep, &buf); 87 } 88 89 if ((err == PWU_SUCCESS) && rops[i]->update) 90 err = rops[i]->update(items, rep, buf); 91 92 if ((err == PWU_SUCCESS) && rops[i]->putpwnam) 93 err = rops[i]->putpwnam(name, oldpw, rep, buf); 94 95 if (rops[i]->unlock) 96 (void) rops[i]->unlock(); 97 98 if (buf) { 99 (void) free(buf); 100 buf = NULL; 101 } 102 if (err == PWU_SUCCESS) { 103 rep_success = i; /* this rep succeeded */ 104 updated |= i; 105 } else if (err != PWU_SUCCESS && err != PWU_NOT_FOUND) { 106 break; 107 } 108 } 109 } 110 111 if (buf) 112 free(buf); 113 114 if (updated_reps) 115 *updated_reps = (updated != REP_NOREP) ? updated : i; 116 117 /* 118 * err contains either 119 * PWU_SUCCESS : everyting went OK 120 * PWU_NOT_FOUND : none of the repositories contained the user 121 * error-code : the specific error that occurred 122 */ 123 if (rep_success != REP_NOREP) { 124 return (PWU_SUCCESS); 125 } else { 126 return (err); 127 } 128 } 129