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