1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <ctype.h> 32*7c478bd9Sstevel@tonic-gate #include <strings.h> 33*7c478bd9Sstevel@tonic-gate #include <pwd.h> 34*7c478bd9Sstevel@tonic-gate #include <shadow.h> 35*7c478bd9Sstevel@tonic-gate #include <netdb.h> 36*7c478bd9Sstevel@tonic-gate #include <mp.h> 37*7c478bd9Sstevel@tonic-gate #include <rpcsvc/nis.h> 38*7c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h> 39*7c478bd9Sstevel@tonic-gate #include <nsswitch.h> 40*7c478bd9Sstevel@tonic-gate #include <ns_sldap.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate extern char *crypt(); 43*7c478bd9Sstevel@tonic-gate extern long random(); 44*7c478bd9Sstevel@tonic-gate extern char *getpassphrase(); 45*7c478bd9Sstevel@tonic-gate extern char *program_name; 46*7c478bd9Sstevel@tonic-gate static const char *CRED_TABLE = "cred.org_dir"; 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #define ROOTKEY_FILE "/etc/.rootkey" 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #ifndef MAXHOSTNAMELEN 51*7c478bd9Sstevel@tonic-gate #define MAXHOSTNAMELEN 256 52*7c478bd9Sstevel@tonic-gate #endif 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #define PK_FILES 1 55*7c478bd9Sstevel@tonic-gate #define PK_YP 2 56*7c478bd9Sstevel@tonic-gate #define PK_NISPLUS 3 57*7c478bd9Sstevel@tonic-gate #define PK_LDAP 4 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #define LDAP_BINDDN_DEFAULT "cn=Directory Manager" 60*7c478bd9Sstevel@tonic-gate #define PROMPTGET_SUCCESS 1 61*7c478bd9Sstevel@tonic-gate #define PROMPTGET_FAIL -1 62*7c478bd9Sstevel@tonic-gate #define PROMPTGET_MEMORY_FAIL -2 63*7c478bd9Sstevel@tonic-gate #define PASSWD_UNMATCHED -3 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate #define FREE_CREDINFO(s) \ 66*7c478bd9Sstevel@tonic-gate if ((s)) { (void) memset((s), 0, strlen((s))); } 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* ************************ switch functions *************************** */ 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /* NSW_NOTSUCCESS NSW_NOTFOUND NSW_UNAVAIL NSW_TRYAGAIN */ 72*7c478bd9Sstevel@tonic-gate #define DEF_ACTION {__NSW_RETURN, __NSW_RETURN, __NSW_CONTINUE, __NSW_CONTINUE} 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate static struct __nsw_lookup lookup_files = {"files", DEF_ACTION, NULL, NULL}, 75*7c478bd9Sstevel@tonic-gate lookup_nis = {"nis", DEF_ACTION, NULL, &lookup_files}; 76*7c478bd9Sstevel@tonic-gate static struct __nsw_switchconfig publickey_default = 77*7c478bd9Sstevel@tonic-gate {0, "publickey", 2, &lookup_nis}; 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate static int get_ldap_bindDN(char **); 80*7c478bd9Sstevel@tonic-gate static int get_ldap_bindPassword(char **); 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* 83*7c478bd9Sstevel@tonic-gate * Prompt the users for a ldap bind DN. If users do not enter a value but just 84*7c478bd9Sstevel@tonic-gate * simply hit the return key, the default bindDN "cn=Directory Manager" 85*7c478bd9Sstevel@tonic-gate * will be used. 86*7c478bd9Sstevel@tonic-gate */ 87*7c478bd9Sstevel@tonic-gate static int 88*7c478bd9Sstevel@tonic-gate get_ldap_bindDN(char **ret_bindDN) { 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate char bindDN[BUFSIZ]; 91*7c478bd9Sstevel@tonic-gate char prompt[BUFSIZ]; 92*7c478bd9Sstevel@tonic-gate int blen, pos; 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate /* set the initial value for bindDN buffer */ 95*7c478bd9Sstevel@tonic-gate (void) memset(bindDN, 0, BUFSIZ); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate (void) snprintf(prompt, BUFSIZ, 98*7c478bd9Sstevel@tonic-gate "\nThe LDAP bind DN and password are required for this update.\n" 99*7c478bd9Sstevel@tonic-gate "If you are not sure what values to enter, please contact your\n" 100*7c478bd9Sstevel@tonic-gate "LDAP administrator.\n\nPlease enter LDAP bind DN [%s]: ", 101*7c478bd9Sstevel@tonic-gate LDAP_BINDDN_DEFAULT); 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate printf(prompt); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate if (fgets(bindDN, sizeof (bindDN), stdin) == NULL) { 106*7c478bd9Sstevel@tonic-gate (void) strlcpy(bindDN, LDAP_BINDDN_DEFAULT, BUFSIZ); 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate blen = strlen(bindDN); 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* Check if the buffer ends with a newline */ 112*7c478bd9Sstevel@tonic-gate if ((blen > 0) && (bindDN[blen - 1] == '\n')) { 113*7c478bd9Sstevel@tonic-gate bindDN[blen - 1] = '\0'; 114*7c478bd9Sstevel@tonic-gate blen -= 1; 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* Remove the white spaces */ 118*7c478bd9Sstevel@tonic-gate if (blen > 0) { 119*7c478bd9Sstevel@tonic-gate for (pos = blen - 1; pos >= 0; pos--) { 120*7c478bd9Sstevel@tonic-gate if (isspace(bindDN[pos])) 121*7c478bd9Sstevel@tonic-gate bindDN[pos] = '\0'; 122*7c478bd9Sstevel@tonic-gate else 123*7c478bd9Sstevel@tonic-gate break; 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate /* Use the default bindDN, if the buffer contains no characters */ 128*7c478bd9Sstevel@tonic-gate if (strlen(bindDN) == 0) 129*7c478bd9Sstevel@tonic-gate (void) strlcpy(bindDN, LDAP_BINDDN_DEFAULT, BUFSIZ); 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate if ((*ret_bindDN = (char *)malloc(strlen(bindDN)+1)) == NULL) { 132*7c478bd9Sstevel@tonic-gate (void) memset(bindDN, 0, BUFSIZ); 133*7c478bd9Sstevel@tonic-gate return (PROMPTGET_MEMORY_FAIL); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate (void) strlcpy(*ret_bindDN, bindDN, strlen(bindDN)+1); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* Clean up and erase the credential info */ 139*7c478bd9Sstevel@tonic-gate (void) memset(bindDN, 0, BUFSIZ); 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate return (PROMPTGET_SUCCESS); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* 146*7c478bd9Sstevel@tonic-gate * Prompt the user for a ldap bind password. 147*7c478bd9Sstevel@tonic-gate */ 148*7c478bd9Sstevel@tonic-gate static int 149*7c478bd9Sstevel@tonic-gate get_ldap_bindPassword(char **ret_bindPass) { 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate char bindPassword[BUFSIZ]; 152*7c478bd9Sstevel@tonic-gate char prompt[BUFSIZ]; 153*7c478bd9Sstevel@tonic-gate char *bindPass = NULL; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* set the initial value for bindPassword buffer */ 156*7c478bd9Sstevel@tonic-gate (void) memset(bindPassword, 0, BUFSIZ); 157*7c478bd9Sstevel@tonic-gate *ret_bindPass = NULL; 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate (void) snprintf(prompt, BUFSIZ, 160*7c478bd9Sstevel@tonic-gate "Please enter LDAP bind password: "); 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate bindPass = getpassphrase(prompt); 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate if (bindPass == NULL) 165*7c478bd9Sstevel@tonic-gate return (PROMPTGET_FAIL); 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate (void) strlcpy(bindPassword, bindPass, BUFSIZ); 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* clean the static buffer returned from getpassphrase call */ 170*7c478bd9Sstevel@tonic-gate (void) memset(bindPass, 0, strlen(bindPass)); 171*7c478bd9Sstevel@tonic-gate bindPass = NULL; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate /* 174*7c478bd9Sstevel@tonic-gate * Re-enter the bind passowrd and compare it with the one 175*7c478bd9Sstevel@tonic-gate * from previous entered. 176*7c478bd9Sstevel@tonic-gate */ 177*7c478bd9Sstevel@tonic-gate (void) snprintf(prompt, BUFSIZ, 178*7c478bd9Sstevel@tonic-gate "Re-enter LDAP bind password to confirm: "); 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate bindPass = getpassphrase(prompt); 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate if (bindPass == NULL) { 183*7c478bd9Sstevel@tonic-gate (void) memset(bindPassword, 0, BUFSIZ); 184*7c478bd9Sstevel@tonic-gate return (PASSWD_UNMATCHED); 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if (strcmp(bindPass, bindPassword) != 0) { 188*7c478bd9Sstevel@tonic-gate (void) memset(bindPassword, 0, BUFSIZ); 189*7c478bd9Sstevel@tonic-gate (void) memset(bindPass, 0, strlen(bindPass)); 190*7c478bd9Sstevel@tonic-gate return (PASSWD_UNMATCHED); 191*7c478bd9Sstevel@tonic-gate } else { 192*7c478bd9Sstevel@tonic-gate (void) memset(bindPass, 0, strlen(bindPass)); 193*7c478bd9Sstevel@tonic-gate if ((*ret_bindPass = (char *)malloc(strlen(bindPassword)+1)) 194*7c478bd9Sstevel@tonic-gate == NULL) { 195*7c478bd9Sstevel@tonic-gate (void) memset(bindPassword, 0, BUFSIZ); 196*7c478bd9Sstevel@tonic-gate return (PROMPTGET_MEMORY_FAIL); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate (void) strlcpy(*ret_bindPass, bindPassword, 200*7c478bd9Sstevel@tonic-gate strlen(bindPassword)+1); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* Clean up and erase the credential info */ 203*7c478bd9Sstevel@tonic-gate (void) memset(bindPassword, 0, BUFSIZ); 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate return (PROMPTGET_SUCCESS); 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate char * 212*7c478bd9Sstevel@tonic-gate switch_policy_str(struct __nsw_switchconfig *conf) 213*7c478bd9Sstevel@tonic-gate { 214*7c478bd9Sstevel@tonic-gate struct __nsw_lookup *look; 215*7c478bd9Sstevel@tonic-gate static char policy[256]; /* 256 is enough for (nis, files...etc) */ 216*7c478bd9Sstevel@tonic-gate int previous = 0; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate memset((char *)policy, 0, 256); 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate for (look = conf->lookups; look; look = look->next) { 221*7c478bd9Sstevel@tonic-gate if (previous) 222*7c478bd9Sstevel@tonic-gate strcat(policy, " "); 223*7c478bd9Sstevel@tonic-gate strcat(policy, look->service_name); 224*7c478bd9Sstevel@tonic-gate previous = 1; 225*7c478bd9Sstevel@tonic-gate } 226*7c478bd9Sstevel@tonic-gate return (policy); 227*7c478bd9Sstevel@tonic-gate } 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate int 230*7c478bd9Sstevel@tonic-gate no_switch_policy(struct __nsw_switchconfig *conf) 231*7c478bd9Sstevel@tonic-gate { 232*7c478bd9Sstevel@tonic-gate return (conf == NULL || conf->lookups == NULL); 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate is_switch_policy(struct __nsw_switchconfig *conf, char *target) 236*7c478bd9Sstevel@tonic-gate { 237*7c478bd9Sstevel@tonic-gate return (conf && 238*7c478bd9Sstevel@tonic-gate conf->lookups && 239*7c478bd9Sstevel@tonic-gate strcmp(conf->lookups->service_name, target) == 0 && 240*7c478bd9Sstevel@tonic-gate conf->lookups->next == NULL); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate char * 244*7c478bd9Sstevel@tonic-gate first_and_only_switch_policy(char *policy, 245*7c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *default_conf, 246*7c478bd9Sstevel@tonic-gate char *head_msg) 247*7c478bd9Sstevel@tonic-gate { 248*7c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *conf; 249*7c478bd9Sstevel@tonic-gate enum __nsw_parse_err perr; 250*7c478bd9Sstevel@tonic-gate int policy_correct = 1; 251*7c478bd9Sstevel@tonic-gate char *target_service = 0; 252*7c478bd9Sstevel@tonic-gate int use_default = 0; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate if (default_conf == 0) 255*7c478bd9Sstevel@tonic-gate default_conf = &publickey_default; 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate conf = __nsw_getconfig(policy, &perr); 258*7c478bd9Sstevel@tonic-gate if (no_switch_policy(conf)) { 259*7c478bd9Sstevel@tonic-gate use_default = 1; 260*7c478bd9Sstevel@tonic-gate conf = default_conf; 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate target_service = conf->lookups->service_name; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if (conf->lookups->next != NULL) { 266*7c478bd9Sstevel@tonic-gate policy_correct = 0; 267*7c478bd9Sstevel@tonic-gate if (use_default) { 268*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 269*7c478bd9Sstevel@tonic-gate "\n%s\n There is no publickey entry in %s.\n", 270*7c478bd9Sstevel@tonic-gate head_msg, __NSW_CONFIG_FILE); 271*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 272*7c478bd9Sstevel@tonic-gate "The default publickey policy is \"publickey: %s\".\n", 273*7c478bd9Sstevel@tonic-gate switch_policy_str(default_conf)); 274*7c478bd9Sstevel@tonic-gate } else 275*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 276*7c478bd9Sstevel@tonic-gate "\n%s\nThe publickey entry in %s is \"publickey: %s\".\n", 277*7c478bd9Sstevel@tonic-gate head_msg, __NSW_CONFIG_FILE, 278*7c478bd9Sstevel@tonic-gate switch_policy_str(conf)); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate if (policy_correct == 0) 282*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 283*7c478bd9Sstevel@tonic-gate "I cannot figure out which publickey database you want to update.\n"); 284*7c478bd9Sstevel@tonic-gate if (!use_default && conf) 285*7c478bd9Sstevel@tonic-gate __nsw_freeconfig(conf); 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate if (policy_correct) 288*7c478bd9Sstevel@tonic-gate return (target_service); 289*7c478bd9Sstevel@tonic-gate else 290*7c478bd9Sstevel@tonic-gate return (0); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate int 296*7c478bd9Sstevel@tonic-gate check_switch_policy(char *policy, char *target_service, 297*7c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *default_conf, 298*7c478bd9Sstevel@tonic-gate char *head_msg, char *tail_msg) 299*7c478bd9Sstevel@tonic-gate { 300*7c478bd9Sstevel@tonic-gate struct __nsw_switchconfig *conf; 301*7c478bd9Sstevel@tonic-gate enum __nsw_parse_err perr; 302*7c478bd9Sstevel@tonic-gate int policy_correct = 1; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate if (default_conf == 0) 305*7c478bd9Sstevel@tonic-gate default_conf = &publickey_default; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate conf = __nsw_getconfig(policy, &perr); 308*7c478bd9Sstevel@tonic-gate if (no_switch_policy(conf)) { 309*7c478bd9Sstevel@tonic-gate if (!is_switch_policy(default_conf, target_service)) { 310*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 311*7c478bd9Sstevel@tonic-gate "\n%s\nThere is no publickey entry in %s.\n", 312*7c478bd9Sstevel@tonic-gate head_msg, __NSW_CONFIG_FILE); 313*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 314*7c478bd9Sstevel@tonic-gate "The default publickey policy is \"publickey: %s\".\n", 315*7c478bd9Sstevel@tonic-gate switch_policy_str(default_conf)); 316*7c478bd9Sstevel@tonic-gate policy_correct = 0; 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate } else if (!is_switch_policy(conf, target_service)) { 319*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 320*7c478bd9Sstevel@tonic-gate "\n%s\nThe publickey entry in %s is \"publickey: %s\".\n", 321*7c478bd9Sstevel@tonic-gate head_msg, __NSW_CONFIG_FILE, 322*7c478bd9Sstevel@tonic-gate switch_policy_str(conf)); 323*7c478bd9Sstevel@tonic-gate policy_correct = 0; 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate /* should we exit ? */ 326*7c478bd9Sstevel@tonic-gate if (policy_correct == 0) 327*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 328*7c478bd9Sstevel@tonic-gate "It should be \"publickey: %s\"%s\n\n", 329*7c478bd9Sstevel@tonic-gate target_service, tail_msg); 330*7c478bd9Sstevel@tonic-gate if (conf) 331*7c478bd9Sstevel@tonic-gate __nsw_freeconfig(conf); 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate return (policy_correct); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate int 337*7c478bd9Sstevel@tonic-gate get_pk_source(char *pk_service) 338*7c478bd9Sstevel@tonic-gate { 339*7c478bd9Sstevel@tonic-gate int db = 0, got_from_switch = 0; 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate /* No service specified, try to figure out from switch */ 342*7c478bd9Sstevel@tonic-gate if (pk_service == 0) { 343*7c478bd9Sstevel@tonic-gate pk_service = first_and_only_switch_policy("publickey", 0, 344*7c478bd9Sstevel@tonic-gate "ERROR:"); 345*7c478bd9Sstevel@tonic-gate if (pk_service == 0) 346*7c478bd9Sstevel@tonic-gate return (0); 347*7c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 348*7c478bd9Sstevel@tonic-gate "Updating %s publickey database.\n", 349*7c478bd9Sstevel@tonic-gate pk_service); 350*7c478bd9Sstevel@tonic-gate got_from_switch = 1; 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate if (strcmp(pk_service, "ldap") == 0) 354*7c478bd9Sstevel@tonic-gate db = PK_LDAP; 355*7c478bd9Sstevel@tonic-gate else if (strcmp(pk_service, "nisplus") == 0) 356*7c478bd9Sstevel@tonic-gate db = PK_NISPLUS; 357*7c478bd9Sstevel@tonic-gate else if (strcmp(pk_service, "nis") == 0) 358*7c478bd9Sstevel@tonic-gate db = PK_YP; 359*7c478bd9Sstevel@tonic-gate else if (strcmp(pk_service, "files") == 0) 360*7c478bd9Sstevel@tonic-gate db = PK_FILES; 361*7c478bd9Sstevel@tonic-gate else return (0); 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate /* 364*7c478bd9Sstevel@tonic-gate * If we didn't get service name from switch, check switch 365*7c478bd9Sstevel@tonic-gate * and print warning about it source of publickeys if not unique 366*7c478bd9Sstevel@tonic-gate */ 367*7c478bd9Sstevel@tonic-gate if (got_from_switch == 0) 368*7c478bd9Sstevel@tonic-gate check_switch_policy("publickey", pk_service, 0, "WARNING:", 369*7c478bd9Sstevel@tonic-gate db == PK_FILES ? "" : 370*7c478bd9Sstevel@tonic-gate "; add 'files' if you want the 'nobody' key."); 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate return (db); /* all passed */ 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate /* ***************************** keylogin stuff *************************** */ 378*7c478bd9Sstevel@tonic-gate int 379*7c478bd9Sstevel@tonic-gate keylogin(char *netname, char *secret) 380*7c478bd9Sstevel@tonic-gate { 381*7c478bd9Sstevel@tonic-gate struct key_netstarg netst; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate netst.st_pub_key[0] = 0; 384*7c478bd9Sstevel@tonic-gate memcpy(netst.st_priv_key, secret, HEXKEYBYTES); 385*7c478bd9Sstevel@tonic-gate netst.st_netname = netname; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate #ifdef NFS_AUTH 388*7c478bd9Sstevel@tonic-gate nra.authtype = AUTH_DES; /* only revoke DES creds */ 389*7c478bd9Sstevel@tonic-gate nra.uid = getuid(); /* use the real uid */ 390*7c478bd9Sstevel@tonic-gate if (_nfssys(NFS_REVAUTH, &nra) < 0) { 391*7c478bd9Sstevel@tonic-gate perror("Warning: NFS credentials not destroyed"); 392*7c478bd9Sstevel@tonic-gate err = 1; 393*7c478bd9Sstevel@tonic-gate } 394*7c478bd9Sstevel@tonic-gate #endif 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate /* do actual key login */ 398*7c478bd9Sstevel@tonic-gate if (key_setnet(&netst) < 0) { 399*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 400*7c478bd9Sstevel@tonic-gate "Could not set %s's secret key\n", netname); 401*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "May be the keyserv is down?\n"); 402*7c478bd9Sstevel@tonic-gate return (0); 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate return (1); 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate /* 409*7c478bd9Sstevel@tonic-gate * XXX unused routine. 410*7c478bd9Sstevel@tonic-gate * Can not locate any routine that is using this write_rootkey() 411*7c478bd9Sstevel@tonic-gate * function. There are 2 other write_rootkey() routines defined in chkey.c 412*7c478bd9Sstevel@tonic-gate * and in cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c. 413*7c478bd9Sstevel@tonic-gate * 414*7c478bd9Sstevel@tonic-gate * write unencrypted secret key into root key file 415*7c478bd9Sstevel@tonic-gate */ 416*7c478bd9Sstevel@tonic-gate write_rootkey(char *secret) 417*7c478bd9Sstevel@tonic-gate { 418*7c478bd9Sstevel@tonic-gate char sbuf[HEXKEYBYTES+2]; 419*7c478bd9Sstevel@tonic-gate int fd, len; 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate strcpy(sbuf, secret); 422*7c478bd9Sstevel@tonic-gate strcat(sbuf, "\n"); 423*7c478bd9Sstevel@tonic-gate len = strlen(sbuf); 424*7c478bd9Sstevel@tonic-gate sbuf[len] = '\0'; 425*7c478bd9Sstevel@tonic-gate unlink(ROOTKEY_FILE); 426*7c478bd9Sstevel@tonic-gate if ((fd = open(ROOTKEY_FILE, O_WRONLY+O_CREAT, 0600)) != -1) { 427*7c478bd9Sstevel@tonic-gate write(fd, sbuf, len+1); 428*7c478bd9Sstevel@tonic-gate close(fd); 429*7c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "Wrote secret key into %s\n", 430*7c478bd9Sstevel@tonic-gate ROOTKEY_FILE); 431*7c478bd9Sstevel@tonic-gate } else { 432*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Could not open %s for update\n", 433*7c478bd9Sstevel@tonic-gate ROOTKEY_FILE); 434*7c478bd9Sstevel@tonic-gate perror(ROOTKEY_FILE); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate /* ****************************** nisplus stuff ************************* */ 439*7c478bd9Sstevel@tonic-gate /* most of it gotten from nisaddcred */ 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate /* Check that someone else don't have the same auth information already */ 443*7c478bd9Sstevel@tonic-gate static 444*7c478bd9Sstevel@tonic-gate nis_error 445*7c478bd9Sstevel@tonic-gate auth_exists(char *princname, char *auth_name, char *auth_type, char *domain) 446*7c478bd9Sstevel@tonic-gate { 447*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+MAXHOSTNAMELEN+64]; 448*7c478bd9Sstevel@tonic-gate nis_result *res; 449*7c478bd9Sstevel@tonic-gate nis_error status; 450*7c478bd9Sstevel@tonic-gate char *foundprinc; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "[auth_name=%s,auth_type=%s],%s.%s", 453*7c478bd9Sstevel@tonic-gate auth_name, auth_type, CRED_TABLE, domain); 454*7c478bd9Sstevel@tonic-gate if (sname[strlen(sname)-1] != '.') 455*7c478bd9Sstevel@tonic-gate strcat(sname, "."); 456*7c478bd9Sstevel@tonic-gate /* Don't want FOLLOW_PATH here */ 457*7c478bd9Sstevel@tonic-gate res = nis_list(sname, 458*7c478bd9Sstevel@tonic-gate MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, 459*7c478bd9Sstevel@tonic-gate NULL, NULL); 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate status = res->status; 462*7c478bd9Sstevel@tonic-gate switch (res->status) { 463*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 464*7c478bd9Sstevel@tonic-gate break; 465*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN : 466*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 467*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 468*7c478bd9Sstevel@tonic-gate program_name); 469*7c478bd9Sstevel@tonic-gate exit(1); 470*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION : 471*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 472*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to look up old credentials.\n", 473*7c478bd9Sstevel@tonic-gate program_name); 474*7c478bd9Sstevel@tonic-gate exit(1); 475*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 476*7c478bd9Sstevel@tonic-gate foundprinc = ENTRY_VAL(res->objects.objects_val, 0); 477*7c478bd9Sstevel@tonic-gate if (nis_dir_cmp(foundprinc, princname) != SAME_NAME) { 478*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 479*7c478bd9Sstevel@tonic-gate "%s: %s credentials with auth_name '%s' already belong to '%s'.\n", 480*7c478bd9Sstevel@tonic-gate program_name, auth_type, auth_name, foundprinc); 481*7c478bd9Sstevel@tonic-gate exit(1); 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate break; 484*7c478bd9Sstevel@tonic-gate default: 485*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 486*7c478bd9Sstevel@tonic-gate "%s: error looking at cred table, NIS+ error: %s\n", 487*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 488*7c478bd9Sstevel@tonic-gate exit(1); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 491*7c478bd9Sstevel@tonic-gate return (status); 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate /* Returns 0 if check fails; 1 if successful. */ 495*7c478bd9Sstevel@tonic-gate static int 496*7c478bd9Sstevel@tonic-gate sanity_checks(nis_princ, netname, domain) 497*7c478bd9Sstevel@tonic-gate char *nis_princ, 498*7c478bd9Sstevel@tonic-gate *netname, 499*7c478bd9Sstevel@tonic-gate *domain; 500*7c478bd9Sstevel@tonic-gate { 501*7c478bd9Sstevel@tonic-gate char netdomainaux[MAXHOSTNAMELEN+1]; 502*7c478bd9Sstevel@tonic-gate char *princdomain, *netdomain; 503*7c478bd9Sstevel@tonic-gate int len; 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate /* Sanity check 0. Do we have a nis+ principal name to work with? */ 506*7c478bd9Sstevel@tonic-gate if (nis_princ == NULL) { 507*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 508*7c478bd9Sstevel@tonic-gate "%s: you must create a \"LOCAL\" credential for '%s' first.\n", 509*7c478bd9Sstevel@tonic-gate program_name, netname); 510*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\tSee nisaddcred(1).\n"); 511*7c478bd9Sstevel@tonic-gate return (0); 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* Sanity check 0.5. NIS+ principal names must be dotted. */ 515*7c478bd9Sstevel@tonic-gate len = strlen(nis_princ); 516*7c478bd9Sstevel@tonic-gate if (nis_princ[len-1] != '.') { 517*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 518*7c478bd9Sstevel@tonic-gate "%s: invalid principal name: '%s' (forgot ending dot?).\n", 519*7c478bd9Sstevel@tonic-gate program_name, nis_princ); 520*7c478bd9Sstevel@tonic-gate return (0); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate /* Sanity check 1. We only deal with one type of netnames. */ 524*7c478bd9Sstevel@tonic-gate if (strncmp(netname, "unix", 4) != 0) { 525*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 526*7c478bd9Sstevel@tonic-gate "%s: unrecognized netname type: '%s'.\n", 527*7c478bd9Sstevel@tonic-gate program_name, netname); 528*7c478bd9Sstevel@tonic-gate return (0); 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate /* Sanity check 2. Should only add DES cred in home domain. */ 532*7c478bd9Sstevel@tonic-gate princdomain = nis_domain_of(nis_princ); 533*7c478bd9Sstevel@tonic-gate if (strcasecmp(princdomain, domain) != 0) { 534*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 535*7c478bd9Sstevel@tonic-gate "%s: domain of principal '%s' does not match destination domain '%s'.\n", 536*7c478bd9Sstevel@tonic-gate program_name, nis_princ, domain); 537*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 538*7c478bd9Sstevel@tonic-gate "Should only add DES credential of principal in its home domain\n"); 539*7c478bd9Sstevel@tonic-gate return (0); 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate /* 543*7c478bd9Sstevel@tonic-gate * Sanity check 3: Make sure netname's domain same as principal's 544*7c478bd9Sstevel@tonic-gate * and don't have extraneous dot at the end. 545*7c478bd9Sstevel@tonic-gate */ 546*7c478bd9Sstevel@tonic-gate netdomain = (char *)strchr(netname, '@'); 547*7c478bd9Sstevel@tonic-gate if (! netdomain || netname[strlen(netname)-1] == '.') { 548*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: invalid netname: '%s'. \n", 549*7c478bd9Sstevel@tonic-gate program_name, netname); 550*7c478bd9Sstevel@tonic-gate return (0); 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate netdomain++; /* skip '@' */ 553*7c478bd9Sstevel@tonic-gate /* make sure we don't run into buffer overflow */ 554*7c478bd9Sstevel@tonic-gate if (strlen(netdomain) > sizeof (netdomainaux)) 555*7c478bd9Sstevel@tonic-gate return (0); 556*7c478bd9Sstevel@tonic-gate strcpy(netdomainaux, netdomain); 557*7c478bd9Sstevel@tonic-gate if (netdomainaux[strlen(netdomainaux)-1] != '.') 558*7c478bd9Sstevel@tonic-gate strcat(netdomainaux, "."); 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate if (strcasecmp(princdomain, netdomainaux) != 0) { 561*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 562*7c478bd9Sstevel@tonic-gate "%s: domain of netname %s should be same as that of principal %s\n", 563*7c478bd9Sstevel@tonic-gate program_name, netname, nis_princ); 564*7c478bd9Sstevel@tonic-gate return (0); 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /* Another principal owns same credentials? (exits if that happens) */ 568*7c478bd9Sstevel@tonic-gate (void) auth_exists(nis_princ, netname, "DES", domain); 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate return (1); /* all passed */ 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate /* 575*7c478bd9Sstevel@tonic-gate * Similar to nis_local_principal in "nis_subr.c" except 576*7c478bd9Sstevel@tonic-gate * this gets the results from the MASTER_ONLY and no FOLLOW_PATH. 577*7c478bd9Sstevel@tonic-gate * We only want the master because we'll be making updates there, 578*7c478bd9Sstevel@tonic-gate * and also the replicas may not have seen the 'nisaddacred local' 579*7c478bd9Sstevel@tonic-gate * that may have just occurred. 580*7c478bd9Sstevel@tonic-gate * Returns NULL if not found. 581*7c478bd9Sstevel@tonic-gate */ 582*7c478bd9Sstevel@tonic-gate char * 583*7c478bd9Sstevel@tonic-gate get_nisplus_principal(directory, uid) 584*7c478bd9Sstevel@tonic-gate char *directory; 585*7c478bd9Sstevel@tonic-gate uid_t uid; 586*7c478bd9Sstevel@tonic-gate { 587*7c478bd9Sstevel@tonic-gate nis_result *res; 588*7c478bd9Sstevel@tonic-gate char buf[NIS_MAXNAMELEN + 1]; 589*7c478bd9Sstevel@tonic-gate int status; 590*7c478bd9Sstevel@tonic-gate static char principal_name[NIS_MAXNAMELEN + 1]; 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if (uid == 0) 593*7c478bd9Sstevel@tonic-gate return (nis_local_host()); 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate /* buf is enough to hold the string, no buffer overflow */ 596*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "[auth_name=%d,auth_type=LOCAL],%s.%s", 597*7c478bd9Sstevel@tonic-gate uid, CRED_TABLE, directory); 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate if (buf[strlen(buf)-1] != '.') 600*7c478bd9Sstevel@tonic-gate strcat(buf, "."); 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate res = nis_list(buf, 603*7c478bd9Sstevel@tonic-gate MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, 604*7c478bd9Sstevel@tonic-gate NULL, NULL); 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate if (res == NULL) { 607*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 608*7c478bd9Sstevel@tonic-gate "%s: unable to get result from NIS+ server.", 609*7c478bd9Sstevel@tonic-gate program_name); 610*7c478bd9Sstevel@tonic-gate exit(1); 611*7c478bd9Sstevel@tonic-gate } 612*7c478bd9Sstevel@tonic-gate switch (res->status) { 613*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 614*7c478bd9Sstevel@tonic-gate if (res->objects.objects_len > 1) { 615*7c478bd9Sstevel@tonic-gate /* 616*7c478bd9Sstevel@tonic-gate * More than one principal with same uid? 617*7c478bd9Sstevel@tonic-gate * something wrong with cred table. Should be unique 618*7c478bd9Sstevel@tonic-gate * Warn user and continue. 619*7c478bd9Sstevel@tonic-gate */ 620*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 621*7c478bd9Sstevel@tonic-gate "%s: LOCAL entry for %d in directory %s not unique", 622*7c478bd9Sstevel@tonic-gate program_name, uid, directory); 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate /* make sure we don't run into buffer overflow */ 625*7c478bd9Sstevel@tonic-gate if (strlen(ENTRY_VAL(res->objects.objects_val, 0)) > 626*7c478bd9Sstevel@tonic-gate sizeof (principal_name)) 627*7c478bd9Sstevel@tonic-gate return (NULL); 628*7c478bd9Sstevel@tonic-gate strcpy(principal_name, 629*7c478bd9Sstevel@tonic-gate ENTRY_VAL(res->objects.objects_val, 0)); 630*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 631*7c478bd9Sstevel@tonic-gate return (principal_name); 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 634*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 635*7c478bd9Sstevel@tonic-gate return (NULL); 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN : 638*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 639*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 640*7c478bd9Sstevel@tonic-gate program_name); 641*7c478bd9Sstevel@tonic-gate exit(1); 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION : 644*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 645*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to update credentials.\n", 646*7c478bd9Sstevel@tonic-gate program_name); 647*7c478bd9Sstevel@tonic-gate exit(1); 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate default: 650*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 651*7c478bd9Sstevel@tonic-gate "%s: error talking to server, NIS+ error: %s.\n", 652*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 653*7c478bd9Sstevel@tonic-gate exit(1); 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate return (NULL); 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate /* Check whether this principal already has this type of credentials */ 661*7c478bd9Sstevel@tonic-gate static nis_error 662*7c478bd9Sstevel@tonic-gate cred_exists(char *nisprinc, char *flavor, char *domain) 663*7c478bd9Sstevel@tonic-gate { 664*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+MAXHOSTNAMELEN+64]; 665*7c478bd9Sstevel@tonic-gate nis_result *res; 666*7c478bd9Sstevel@tonic-gate nis_error status; 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "[cname=\"%s\",auth_type=%s],%s.%s", 669*7c478bd9Sstevel@tonic-gate nisprinc, flavor, CRED_TABLE, domain); 670*7c478bd9Sstevel@tonic-gate if (sname[strlen(sname)-1] != '.') 671*7c478bd9Sstevel@tonic-gate strcat(sname, "."); 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate /* Don't want FOLLOW_PATH here */ 674*7c478bd9Sstevel@tonic-gate res = nis_list(sname, 675*7c478bd9Sstevel@tonic-gate MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS, 676*7c478bd9Sstevel@tonic-gate NULL, NULL); 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate status = res->status; 679*7c478bd9Sstevel@tonic-gate switch (status) { 680*7c478bd9Sstevel@tonic-gate case NIS_NOTFOUND: 681*7c478bd9Sstevel@tonic-gate break; 682*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 683*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 684*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 685*7c478bd9Sstevel@tonic-gate program_name); 686*7c478bd9Sstevel@tonic-gate exit(1); 687*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION: 688*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 689*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to look at credentials table\n", 690*7c478bd9Sstevel@tonic-gate program_name); 691*7c478bd9Sstevel@tonic-gate exit(1); 692*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 693*7c478bd9Sstevel@tonic-gate case NIS_S_SUCCESS: 694*7c478bd9Sstevel@tonic-gate break; 695*7c478bd9Sstevel@tonic-gate default: 696*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 697*7c478bd9Sstevel@tonic-gate "%s: error looking at cred table, NIS+ error: %s\n", 698*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 699*7c478bd9Sstevel@tonic-gate exit(1); 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 702*7c478bd9Sstevel@tonic-gate return (status); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate /* Returns 0 if operation fails; 1 if successful. */ 707*7c478bd9Sstevel@tonic-gate static 708*7c478bd9Sstevel@tonic-gate int 709*7c478bd9Sstevel@tonic-gate modify_cred_obj(obj, domain) 710*7c478bd9Sstevel@tonic-gate char *domain; 711*7c478bd9Sstevel@tonic-gate nis_object *obj; 712*7c478bd9Sstevel@tonic-gate { 713*7c478bd9Sstevel@tonic-gate int status = 0; 714*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; 715*7c478bd9Sstevel@tonic-gate nis_result *res; 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "%s.%s", CRED_TABLE, domain); 718*7c478bd9Sstevel@tonic-gate res = nis_modify_entry(sname, obj, 0); 719*7c478bd9Sstevel@tonic-gate switch (res->status) { 720*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN : 721*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 722*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 723*7c478bd9Sstevel@tonic-gate program_name); 724*7c478bd9Sstevel@tonic-gate exit(1); 725*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION : 726*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 727*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to update credentials.\n", 728*7c478bd9Sstevel@tonic-gate program_name); 729*7c478bd9Sstevel@tonic-gate exit(1); 730*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS : 731*7c478bd9Sstevel@tonic-gate status = 1; 732*7c478bd9Sstevel@tonic-gate break; 733*7c478bd9Sstevel@tonic-gate default: 734*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 735*7c478bd9Sstevel@tonic-gate "%s: error modifying credential, NIS+ error: %s.\n", 736*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 737*7c478bd9Sstevel@tonic-gate exit(1); 738*7c478bd9Sstevel@tonic-gate } 739*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 740*7c478bd9Sstevel@tonic-gate return (status); 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate static 745*7c478bd9Sstevel@tonic-gate int 746*7c478bd9Sstevel@tonic-gate add_cred_obj(obj, domain) 747*7c478bd9Sstevel@tonic-gate char *domain; 748*7c478bd9Sstevel@tonic-gate nis_object *obj; 749*7c478bd9Sstevel@tonic-gate { 750*7c478bd9Sstevel@tonic-gate int status = 0; 751*7c478bd9Sstevel@tonic-gate char sname[NIS_MAXNAMELEN+1]; 752*7c478bd9Sstevel@tonic-gate nis_result *res; 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate /* Assume check for cred_exists performed already */ 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate (void) sprintf(sname, "%s.%s", CRED_TABLE, domain); 757*7c478bd9Sstevel@tonic-gate res = nis_add_entry(sname, obj, 0); 758*7c478bd9Sstevel@tonic-gate switch (res->status) { 759*7c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN : 760*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 761*7c478bd9Sstevel@tonic-gate "%s: NIS+ server busy, try again later.\n", 762*7c478bd9Sstevel@tonic-gate program_name); 763*7c478bd9Sstevel@tonic-gate exit(1); 764*7c478bd9Sstevel@tonic-gate case NIS_PERMISSION : 765*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 766*7c478bd9Sstevel@tonic-gate "%s: insufficient permission to update credentials.\n", 767*7c478bd9Sstevel@tonic-gate program_name); 768*7c478bd9Sstevel@tonic-gate exit(1); 769*7c478bd9Sstevel@tonic-gate case NIS_SUCCESS : 770*7c478bd9Sstevel@tonic-gate status = 1; 771*7c478bd9Sstevel@tonic-gate break; 772*7c478bd9Sstevel@tonic-gate default: 773*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 774*7c478bd9Sstevel@tonic-gate "%s: error creating credential, NIS+ error: %s.\n", 775*7c478bd9Sstevel@tonic-gate program_name, nis_sperrno(res->status)); 776*7c478bd9Sstevel@tonic-gate exit(1); 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate nis_freeresult(res); 779*7c478bd9Sstevel@tonic-gate return (status); 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate nis_object * 783*7c478bd9Sstevel@tonic-gate init_entry() 784*7c478bd9Sstevel@tonic-gate { 785*7c478bd9Sstevel@tonic-gate static nis_object obj; 786*7c478bd9Sstevel@tonic-gate static entry_col cred_data[10]; 787*7c478bd9Sstevel@tonic-gate entry_obj *eo; 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate memset((char *)(&obj), 0, sizeof (obj)); 790*7c478bd9Sstevel@tonic-gate memset((char *)(cred_data), 0, sizeof (entry_col) * 10); 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate obj.zo_name = "cred"; 793*7c478bd9Sstevel@tonic-gate obj.zo_group = ""; 794*7c478bd9Sstevel@tonic-gate obj.zo_ttl = 43200; 795*7c478bd9Sstevel@tonic-gate obj.zo_data.zo_type = NIS_ENTRY_OBJ; 796*7c478bd9Sstevel@tonic-gate eo = &(obj.EN_data); 797*7c478bd9Sstevel@tonic-gate eo->en_type = "cred_tbl"; 798*7c478bd9Sstevel@tonic-gate eo->en_cols.en_cols_val = cred_data; 799*7c478bd9Sstevel@tonic-gate eo->en_cols.en_cols_len = 5; 800*7c478bd9Sstevel@tonic-gate cred_data[4].ec_flags |= EN_CRYPT; 801*7c478bd9Sstevel@tonic-gate return (&obj); 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate static char *attrFilter[] = { 806*7c478bd9Sstevel@tonic-gate "objectclass", 807*7c478bd9Sstevel@tonic-gate "nispublickey", 808*7c478bd9Sstevel@tonic-gate "nissecretkey", 809*7c478bd9Sstevel@tonic-gate (char *)NULL 810*7c478bd9Sstevel@tonic-gate }; 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate /* Determines if there is a NisKeyObject objectclass in a given entry */ 814*7c478bd9Sstevel@tonic-gate static int 815*7c478bd9Sstevel@tonic-gate ldap_keyobj_exist(ns_ldap_entry_t *entry) 816*7c478bd9Sstevel@tonic-gate { 817*7c478bd9Sstevel@tonic-gate char **fattrs; 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate fattrs = __ns_ldap_getAttr(entry, "objectClass"); 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate if (fattrs == NULL) 822*7c478bd9Sstevel@tonic-gate return (1); 823*7c478bd9Sstevel@tonic-gate 824*7c478bd9Sstevel@tonic-gate while (*fattrs) { 825*7c478bd9Sstevel@tonic-gate if (strcasecmp("NisKeyObject", *fattrs) == 0) 826*7c478bd9Sstevel@tonic-gate return (1); 827*7c478bd9Sstevel@tonic-gate fattrs++; 828*7c478bd9Sstevel@tonic-gate } 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate return (0); 831*7c478bd9Sstevel@tonic-gate } 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate static char *keyAttrs[] = { 835*7c478bd9Sstevel@tonic-gate "nispublickey", 836*7c478bd9Sstevel@tonic-gate "nissecretkey", 837*7c478bd9Sstevel@tonic-gate NULL 838*7c478bd9Sstevel@tonic-gate }; 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate /* 841*7c478bd9Sstevel@tonic-gate * Replace or append new attribute value(s) to an attribute. 842*7c478bd9Sstevel@tonic-gate * Don't care about memory leaks, because program is short running. 843*7c478bd9Sstevel@tonic-gate */ 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate static int 846*7c478bd9Sstevel@tonic-gate ldap_attr_mod(ns_ldap_entry_t *entry, 847*7c478bd9Sstevel@tonic-gate char *mechname, 848*7c478bd9Sstevel@tonic-gate char *public, 849*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t **pkeyattrs, 850*7c478bd9Sstevel@tonic-gate char *crypt, 851*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t **ckeyattrs) 852*7c478bd9Sstevel@tonic-gate { 853*7c478bd9Sstevel@tonic-gate char **alist[2]; 854*7c478bd9Sstevel@tonic-gate char *keys[2]; 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate char *mechfilter; 857*7c478bd9Sstevel@tonic-gate int mechfilterlen; 858*7c478bd9Sstevel@tonic-gate int q = 0; 859*7c478bd9Sstevel@tonic-gate int i, j; 860*7c478bd9Sstevel@tonic-gate int keycount[] = {0, 0}; 861*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t *attrs; 862*7c478bd9Sstevel@tonic-gate 863*7c478bd9Sstevel@tonic-gate keys[0] = public; 864*7c478bd9Sstevel@tonic-gate keys[1] = crypt; 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate mechfilter = (char *)malloc(strlen(mechname) + 3); 867*7c478bd9Sstevel@tonic-gate if (mechfilter == NULL) 868*7c478bd9Sstevel@tonic-gate return (0); 869*7c478bd9Sstevel@tonic-gate sprintf(mechfilter, "{%s}", mechname); 870*7c478bd9Sstevel@tonic-gate mechfilterlen = strlen(mechfilter); 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate for (q = 0; keyAttrs[q] != NULL; q++) { 873*7c478bd9Sstevel@tonic-gate int found = 0; 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate for (i = 0; i < entry->attr_count; i++) { 876*7c478bd9Sstevel@tonic-gate int rep = 0; 877*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t *attr = entry->attr_pair[i]; 878*7c478bd9Sstevel@tonic-gate char *name = attr->attrname; 879*7c478bd9Sstevel@tonic-gate int count = 0; 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate if (strcasecmp(keyAttrs[q], name) == 0) { 882*7c478bd9Sstevel@tonic-gate found++; 883*7c478bd9Sstevel@tonic-gate count = attr->value_count; 884*7c478bd9Sstevel@tonic-gate alist[q] = (char **)malloc(sizeof (char *) * (count + 1)); 885*7c478bd9Sstevel@tonic-gate if (alist[q] == NULL) 886*7c478bd9Sstevel@tonic-gate return (0); 887*7c478bd9Sstevel@tonic-gate alist[q][attr->value_count] = NULL; 888*7c478bd9Sstevel@tonic-gate for (j = 0; j < attr->value_count; j++) { 889*7c478bd9Sstevel@tonic-gate char *val = attr->attrvalue[j]; 890*7c478bd9Sstevel@tonic-gate if (strncasecmp(val, mechfilter, 891*7c478bd9Sstevel@tonic-gate mechfilterlen) == 0) { 892*7c478bd9Sstevel@tonic-gate /* Replace entry */ 893*7c478bd9Sstevel@tonic-gate rep++; 894*7c478bd9Sstevel@tonic-gate alist[q][j] = keys[q]; 895*7c478bd9Sstevel@tonic-gate } else 896*7c478bd9Sstevel@tonic-gate alist[q][j] = val; 897*7c478bd9Sstevel@tonic-gate ++keycount[q]; 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate if (!rep) { 900*7c478bd9Sstevel@tonic-gate /* Add entry to list */ 901*7c478bd9Sstevel@tonic-gate alist[q] = (char **)realloc(alist[q], 902*7c478bd9Sstevel@tonic-gate sizeof (char *) * (count + 2)); 903*7c478bd9Sstevel@tonic-gate if (alist[q] == NULL) 904*7c478bd9Sstevel@tonic-gate return (0); 905*7c478bd9Sstevel@tonic-gate alist[q][attr->value_count + 1] = NULL; 906*7c478bd9Sstevel@tonic-gate alist[q][attr->value_count] = keys[q]; 907*7c478bd9Sstevel@tonic-gate ++keycount[q]; 908*7c478bd9Sstevel@tonic-gate } 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate if (!found) { 912*7c478bd9Sstevel@tonic-gate /* Attribute does not exist, add entry anyways */ 913*7c478bd9Sstevel@tonic-gate alist[q] = (char **)malloc(sizeof (char *) * 2); 914*7c478bd9Sstevel@tonic-gate if (alist[q] == NULL) 915*7c478bd9Sstevel@tonic-gate return (0); 916*7c478bd9Sstevel@tonic-gate alist[q][0] = keys[q]; 917*7c478bd9Sstevel@tonic-gate alist[q][1] = NULL; 918*7c478bd9Sstevel@tonic-gate ++keycount[q]; 919*7c478bd9Sstevel@tonic-gate } 920*7c478bd9Sstevel@tonic-gate } 921*7c478bd9Sstevel@tonic-gate if ((attrs = (ns_ldap_attr_t *)calloc(1, 922*7c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t))) == NULL) 923*7c478bd9Sstevel@tonic-gate return (0); 924*7c478bd9Sstevel@tonic-gate attrs->attrname = "nisPublicKey"; 925*7c478bd9Sstevel@tonic-gate attrs->attrvalue = alist[0]; 926*7c478bd9Sstevel@tonic-gate attrs->value_count = keycount[0]; 927*7c478bd9Sstevel@tonic-gate *pkeyattrs = attrs; 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate if ((attrs = (ns_ldap_attr_t *)calloc(1, 930*7c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t))) == NULL) 931*7c478bd9Sstevel@tonic-gate return (0); 932*7c478bd9Sstevel@tonic-gate attrs->attrname = "nisSecretKey"; 933*7c478bd9Sstevel@tonic-gate attrs->attrvalue = alist[1]; 934*7c478bd9Sstevel@tonic-gate attrs->value_count = keycount[1]; 935*7c478bd9Sstevel@tonic-gate *ckeyattrs = attrs; 936*7c478bd9Sstevel@tonic-gate return (1); 937*7c478bd9Sstevel@tonic-gate } 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate /* 941*7c478bd9Sstevel@tonic-gate * Do the actual Add or update of attributes in attrs. 942*7c478bd9Sstevel@tonic-gate * The parameter 'update4host' is a flag that tells the function which 943*7c478bd9Sstevel@tonic-gate * DN and password should be used to bind to ldap. If it is an update 944*7c478bd9Sstevel@tonic-gate * for a host (update4host > 0), the two parameters "bindDN" and 945*7c478bd9Sstevel@tonic-gate * "bindPasswd" would be used to bind as the directory manager, 946*7c478bd9Sstevel@tonic-gate * otherwise "dn" and "passwd" would be used to bind as an individual 947*7c478bd9Sstevel@tonic-gate * user. 948*7c478bd9Sstevel@tonic-gate */ 949*7c478bd9Sstevel@tonic-gate static void 950*7c478bd9Sstevel@tonic-gate update_ldap_attr(const char *dn, 951*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t **attrs, 952*7c478bd9Sstevel@tonic-gate const char *passwd, 953*7c478bd9Sstevel@tonic-gate int add, 954*7c478bd9Sstevel@tonic-gate int update4host, 955*7c478bd9Sstevel@tonic-gate const char *bindDN, 956*7c478bd9Sstevel@tonic-gate const char *bindPasswd) 957*7c478bd9Sstevel@tonic-gate { 958*7c478bd9Sstevel@tonic-gate int ldaprc; 959*7c478bd9Sstevel@tonic-gate int authstried = 0; 960*7c478bd9Sstevel@tonic-gate char *msg; 961*7c478bd9Sstevel@tonic-gate char *ldap_pw; 962*7c478bd9Sstevel@tonic-gate char **certpath = NULL; 963*7c478bd9Sstevel@tonic-gate ns_auth_t **app; 964*7c478bd9Sstevel@tonic-gate ns_auth_t **authpp = NULL; 965*7c478bd9Sstevel@tonic-gate ns_auth_t *authp = NULL; 966*7c478bd9Sstevel@tonic-gate ns_cred_t *credp; 967*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *errorp = NULL; 968*7c478bd9Sstevel@tonic-gate int status; 969*7c478bd9Sstevel@tonic-gate 970*7c478bd9Sstevel@tonic-gate if ((credp = (ns_cred_t *)calloc(1, sizeof (ns_cred_t))) == NULL) { 971*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Can not allocate cred buffer.\n"); 972*7c478bd9Sstevel@tonic-gate goto out; 973*7c478bd9Sstevel@tonic-gate } 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate /* 976*7c478bd9Sstevel@tonic-gate * if this is an update for host, use the bindDN from the 977*7c478bd9Sstevel@tonic-gate * command prompt, otherwise use user's DN directly. 978*7c478bd9Sstevel@tonic-gate */ 979*7c478bd9Sstevel@tonic-gate if (update4host) 980*7c478bd9Sstevel@tonic-gate credp->cred.unix_cred.userID = strdup(bindDN); 981*7c478bd9Sstevel@tonic-gate else 982*7c478bd9Sstevel@tonic-gate credp->cred.unix_cred.userID = strdup(dn); 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate if (credp->cred.unix_cred.userID == NULL) { 985*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Memory allocation failure (userID)\n"); 986*7c478bd9Sstevel@tonic-gate goto out; 987*7c478bd9Sstevel@tonic-gate } 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate if (update4host) { 990*7c478bd9Sstevel@tonic-gate credp->cred.unix_cred.passwd = strdup(bindPasswd); 991*7c478bd9Sstevel@tonic-gate } else { 992*7c478bd9Sstevel@tonic-gate if (passwd) 993*7c478bd9Sstevel@tonic-gate credp->cred.unix_cred.passwd = strdup(passwd); 994*7c478bd9Sstevel@tonic-gate else { 995*7c478bd9Sstevel@tonic-gate /* Make sure a valid password is received. */ 996*7c478bd9Sstevel@tonic-gate status = get_ldap_bindPassword(&ldap_pw); 997*7c478bd9Sstevel@tonic-gate 998*7c478bd9Sstevel@tonic-gate if (status != PROMPTGET_SUCCESS) { 999*7c478bd9Sstevel@tonic-gate if (!ldap_pw) 1000*7c478bd9Sstevel@tonic-gate free(ldap_pw); 1001*7c478bd9Sstevel@tonic-gate goto out; 1002*7c478bd9Sstevel@tonic-gate } 1003*7c478bd9Sstevel@tonic-gate credp->cred.unix_cred.passwd = ldap_pw; 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate } 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate if (credp->cred.unix_cred.passwd == NULL) { 1008*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Memory allocation failure (passwd)\n"); 1009*7c478bd9Sstevel@tonic-gate goto out; 1010*7c478bd9Sstevel@tonic-gate } 1011*7c478bd9Sstevel@tonic-gate 1012*7c478bd9Sstevel@tonic-gate /* get host certificate path, if one is configured */ 1013*7c478bd9Sstevel@tonic-gate if (__ns_ldap_getParam(NS_LDAP_HOST_CERTPATH_P, 1014*7c478bd9Sstevel@tonic-gate (void ***)&certpath, &errorp) != NS_LDAP_SUCCESS) 1015*7c478bd9Sstevel@tonic-gate goto out; 1016*7c478bd9Sstevel@tonic-gate 1017*7c478bd9Sstevel@tonic-gate if (certpath && *certpath) 1018*7c478bd9Sstevel@tonic-gate credp->hostcertpath = *certpath; 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate /* Load the service specific authentication method */ 1021*7c478bd9Sstevel@tonic-gate if (__ns_ldap_getServiceAuthMethods("keyserv", &authpp, &errorp) != 1022*7c478bd9Sstevel@tonic-gate NS_LDAP_SUCCESS) 1023*7c478bd9Sstevel@tonic-gate goto out; 1024*7c478bd9Sstevel@tonic-gate 1025*7c478bd9Sstevel@tonic-gate /* 1026*7c478bd9Sstevel@tonic-gate * if authpp is null, there is no serviceAuthenticationMethod 1027*7c478bd9Sstevel@tonic-gate * try default authenticationMethod 1028*7c478bd9Sstevel@tonic-gate */ 1029*7c478bd9Sstevel@tonic-gate if (authpp == NULL) { 1030*7c478bd9Sstevel@tonic-gate if (__ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp, 1031*7c478bd9Sstevel@tonic-gate &errorp) != NS_LDAP_SUCCESS) 1032*7c478bd9Sstevel@tonic-gate goto out; 1033*7c478bd9Sstevel@tonic-gate } 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate /* 1036*7c478bd9Sstevel@tonic-gate * if authpp is still null, then can not authenticate, log 1037*7c478bd9Sstevel@tonic-gate * error message and return error 1038*7c478bd9Sstevel@tonic-gate */ 1039*7c478bd9Sstevel@tonic-gate if (authpp == NULL) { 1040*7c478bd9Sstevel@tonic-gate fprintf(stderr, "No LDAP authentication method configured.\n" 1041*7c478bd9Sstevel@tonic-gate " configured.\n"); 1042*7c478bd9Sstevel@tonic-gate goto out; 1043*7c478bd9Sstevel@tonic-gate } 1044*7c478bd9Sstevel@tonic-gate 1045*7c478bd9Sstevel@tonic-gate /* 1046*7c478bd9Sstevel@tonic-gate * Walk the array and try all authentication methods in order except 1047*7c478bd9Sstevel@tonic-gate * for "none". 1048*7c478bd9Sstevel@tonic-gate */ 1049*7c478bd9Sstevel@tonic-gate for (app = authpp; *app; app++) { 1050*7c478bd9Sstevel@tonic-gate authp = *app; 1051*7c478bd9Sstevel@tonic-gate /* what about disabling other mechanisms? "tls:sasl/EXTERNAL" */ 1052*7c478bd9Sstevel@tonic-gate if (authp->type == NS_LDAP_AUTH_NONE) 1053*7c478bd9Sstevel@tonic-gate continue; 1054*7c478bd9Sstevel@tonic-gate authstried++; 1055*7c478bd9Sstevel@tonic-gate credp->auth.type = authp->type; 1056*7c478bd9Sstevel@tonic-gate credp->auth.tlstype = authp->tlstype; 1057*7c478bd9Sstevel@tonic-gate credp->auth.saslmech = authp->saslmech; 1058*7c478bd9Sstevel@tonic-gate credp->auth.saslopt = authp->saslopt; 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate if (add == TRUE) 1061*7c478bd9Sstevel@tonic-gate ldaprc = __ns_ldap_addAttr("publickey", dn, 1062*7c478bd9Sstevel@tonic-gate (const ns_ldap_attr_t * const *)attrs, 1063*7c478bd9Sstevel@tonic-gate credp, NULL, &errorp); 1064*7c478bd9Sstevel@tonic-gate else 1065*7c478bd9Sstevel@tonic-gate ldaprc = __ns_ldap_repAttr("publickey", dn, 1066*7c478bd9Sstevel@tonic-gate (const ns_ldap_attr_t * const *)attrs, 1067*7c478bd9Sstevel@tonic-gate credp, NULL, &errorp); 1068*7c478bd9Sstevel@tonic-gate if (ldaprc == NS_LDAP_SUCCESS) { 1069*7c478bd9Sstevel@tonic-gate /* clean up ns_cred_t structure in memory */ 1070*7c478bd9Sstevel@tonic-gate if (credp != NULL) 1071*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeCred(&credp); 1072*7c478bd9Sstevel@tonic-gate return; 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate /* XXX add checking for cases of authentication errors */ 1076*7c478bd9Sstevel@tonic-gate if ((ldaprc == NS_LDAP_INTERNAL) && 1077*7c478bd9Sstevel@tonic-gate ((errorp->status == LDAP_INAPPROPRIATE_AUTH) || 1078*7c478bd9Sstevel@tonic-gate (errorp->status == LDAP_INVALID_CREDENTIALS))) { 1079*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP authentication failed.\n"); 1080*7c478bd9Sstevel@tonic-gate goto out; 1081*7c478bd9Sstevel@tonic-gate } 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate if (authstried == 0) 1084*7c478bd9Sstevel@tonic-gate fprintf(stderr, "No legal authentication method configured.\n"); 1085*7c478bd9Sstevel@tonic-gate 1086*7c478bd9Sstevel@tonic-gate out: 1087*7c478bd9Sstevel@tonic-gate /* clean up ns_cred_t structure in memory */ 1088*7c478bd9Sstevel@tonic-gate if (credp != NULL) { 1089*7c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeCred(&credp); 1090*7c478bd9Sstevel@tonic-gate } 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate if (errorp) { 1093*7c478bd9Sstevel@tonic-gate __ns_ldap_err2str(errorp->status, &msg); 1094*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP error: %s.\n", msg); 1095*7c478bd9Sstevel@tonic-gate } 1096*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", program_name); 1097*7c478bd9Sstevel@tonic-gate exit(1); 1098*7c478bd9Sstevel@tonic-gate } 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate /* 1102*7c478bd9Sstevel@tonic-gate * Update LDAP nisplublickey entry with new key information via SLDAP. 1103*7c478bd9Sstevel@tonic-gate * Free and clean up memory that stores credential data soon after 1104*7c478bd9Sstevel@tonic-gate * they are not used or an error comes up. 1105*7c478bd9Sstevel@tonic-gate */ 1106*7c478bd9Sstevel@tonic-gate int 1107*7c478bd9Sstevel@tonic-gate ldap_update(char *mechname, 1108*7c478bd9Sstevel@tonic-gate char *netname, 1109*7c478bd9Sstevel@tonic-gate char *public, 1110*7c478bd9Sstevel@tonic-gate char *crypt, 1111*7c478bd9Sstevel@tonic-gate char *passwd) 1112*7c478bd9Sstevel@tonic-gate { 1113*7c478bd9Sstevel@tonic-gate char *netnamecpy; 1114*7c478bd9Sstevel@tonic-gate char *id; 1115*7c478bd9Sstevel@tonic-gate char *domain; 1116*7c478bd9Sstevel@tonic-gate char *dn; 1117*7c478bd9Sstevel@tonic-gate char *db; 1118*7c478bd9Sstevel@tonic-gate char *filter; 1119*7c478bd9Sstevel@tonic-gate ns_ldap_error_t *errorp; 1120*7c478bd9Sstevel@tonic-gate char *pkeyatval, *ckeyatval; 1121*7c478bd9Sstevel@tonic-gate ns_ldap_result_t *res; 1122*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t *pattrs, *cattrs; 1123*7c478bd9Sstevel@tonic-gate int update4host = FALSE; 1124*7c478bd9Sstevel@tonic-gate char *bindDN = NULL; 1125*7c478bd9Sstevel@tonic-gate char *bindPasswd = NULL; 1126*7c478bd9Sstevel@tonic-gate int status; 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate /* Generate DN */ 1129*7c478bd9Sstevel@tonic-gate if ((netnamecpy = strdup(netname)) == NULL) 1130*7c478bd9Sstevel@tonic-gate return (0); 1131*7c478bd9Sstevel@tonic-gate if (((id = strchr(netnamecpy, '.')) == NULL) || 1132*7c478bd9Sstevel@tonic-gate ((domain = strchr(netnamecpy, '@')) == NULL)) 1133*7c478bd9Sstevel@tonic-gate return (0); 1134*7c478bd9Sstevel@tonic-gate else { 1135*7c478bd9Sstevel@tonic-gate *domain++ = '\0'; 1136*7c478bd9Sstevel@tonic-gate *id++ = '\0'; 1137*7c478bd9Sstevel@tonic-gate 1138*7c478bd9Sstevel@tonic-gate id = strdup(id); 1139*7c478bd9Sstevel@tonic-gate if (id == NULL) { 1140*7c478bd9Sstevel@tonic-gate free(netnamecpy); 1141*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP memory error (id)\n"); 1142*7c478bd9Sstevel@tonic-gate return (0); 1143*7c478bd9Sstevel@tonic-gate } 1144*7c478bd9Sstevel@tonic-gate domain = strdup(domain); 1145*7c478bd9Sstevel@tonic-gate if (domain == NULL) { 1146*7c478bd9Sstevel@tonic-gate free(netnamecpy); 1147*7c478bd9Sstevel@tonic-gate free(id); 1148*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP memory error (domain)\n"); 1149*7c478bd9Sstevel@tonic-gate return (0); 1150*7c478bd9Sstevel@tonic-gate } 1151*7c478bd9Sstevel@tonic-gate free(netnamecpy); 1152*7c478bd9Sstevel@tonic-gate } 1153*7c478bd9Sstevel@tonic-gate 1154*7c478bd9Sstevel@tonic-gate if (isdigit(*id)) { 1155*7c478bd9Sstevel@tonic-gate /* We be user. */ 1156*7c478bd9Sstevel@tonic-gate __ns_ldap_uid2dn(id, &dn, NULL, &errorp); 1157*7c478bd9Sstevel@tonic-gate if (dn == NULL) { 1158*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Could not obtain LDAP dn\n"); 1159*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1160*7c478bd9Sstevel@tonic-gate program_name); 1161*7c478bd9Sstevel@tonic-gate exit(1); 1162*7c478bd9Sstevel@tonic-gate } 1163*7c478bd9Sstevel@tonic-gate db = "passwd"; 1164*7c478bd9Sstevel@tonic-gate filter = (char *)malloc(strlen(id) + 13); 1165*7c478bd9Sstevel@tonic-gate if (filter) 1166*7c478bd9Sstevel@tonic-gate sprintf(filter, "(uidnumber=%s)", id); 1167*7c478bd9Sstevel@tonic-gate else { 1168*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Can not allocate filter buffer.\n"); 1169*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1170*7c478bd9Sstevel@tonic-gate program_name); 1171*7c478bd9Sstevel@tonic-gate exit(1); 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate } else { 1174*7c478bd9Sstevel@tonic-gate /* We be host. */ 1175*7c478bd9Sstevel@tonic-gate update4host = TRUE; 1176*7c478bd9Sstevel@tonic-gate 1177*7c478bd9Sstevel@tonic-gate __ns_ldap_host2dn(id, NULL, &dn, NULL, &errorp); 1178*7c478bd9Sstevel@tonic-gate if (dn == NULL) { 1179*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Could not obtain LDAP dn\n"); 1180*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1181*7c478bd9Sstevel@tonic-gate program_name); 1182*7c478bd9Sstevel@tonic-gate exit(1); 1183*7c478bd9Sstevel@tonic-gate } 1184*7c478bd9Sstevel@tonic-gate 1185*7c478bd9Sstevel@tonic-gate db = "hosts"; 1186*7c478bd9Sstevel@tonic-gate filter = (char *)malloc(strlen(id) + 6); 1187*7c478bd9Sstevel@tonic-gate if (filter) 1188*7c478bd9Sstevel@tonic-gate sprintf(filter, "(cn=%s)", id); 1189*7c478bd9Sstevel@tonic-gate else { 1190*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Can not allocate filter buffer.\n"); 1191*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1192*7c478bd9Sstevel@tonic-gate program_name); 1193*7c478bd9Sstevel@tonic-gate exit(1); 1194*7c478bd9Sstevel@tonic-gate } 1195*7c478bd9Sstevel@tonic-gate 1196*7c478bd9Sstevel@tonic-gate /* Prompt for ldap bind DN for entry udpates */ 1197*7c478bd9Sstevel@tonic-gate status = get_ldap_bindDN(&bindDN); 1198*7c478bd9Sstevel@tonic-gate 1199*7c478bd9Sstevel@tonic-gate if (status != PROMPTGET_SUCCESS) { 1200*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1201*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1202*7c478bd9Sstevel@tonic-gate "Failed to get a valid LDAP bind DN.\n" 1203*7c478bd9Sstevel@tonic-gate "%s: key-pair(s) unchanged.\n", 1204*7c478bd9Sstevel@tonic-gate program_name); 1205*7c478bd9Sstevel@tonic-gate exit(1); 1206*7c478bd9Sstevel@tonic-gate } 1207*7c478bd9Sstevel@tonic-gate 1208*7c478bd9Sstevel@tonic-gate /* Prompt for ldap bind password */ 1209*7c478bd9Sstevel@tonic-gate status = get_ldap_bindPassword(&bindPasswd); 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate if (status != PROMPTGET_SUCCESS) { 1212*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1213*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1214*7c478bd9Sstevel@tonic-gate 1215*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1216*7c478bd9Sstevel@tonic-gate "Failed to get a valid LDAP bind password." 1217*7c478bd9Sstevel@tonic-gate "\n%s: key-pair(s) unchanged.\n", 1218*7c478bd9Sstevel@tonic-gate program_name); 1219*7c478bd9Sstevel@tonic-gate exit(1); 1220*7c478bd9Sstevel@tonic-gate } 1221*7c478bd9Sstevel@tonic-gate } 1222*7c478bd9Sstevel@tonic-gate 1223*7c478bd9Sstevel@tonic-gate /* Construct attribute values */ 1224*7c478bd9Sstevel@tonic-gate pkeyatval = (char *)malloc(strlen(mechname) + strlen(public) + 3); 1225*7c478bd9Sstevel@tonic-gate if (pkeyatval == NULL) { 1226*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1227*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1228*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP memory error (pkeyatval)\n"); 1229*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", program_name); 1230*7c478bd9Sstevel@tonic-gate exit(1); 1231*7c478bd9Sstevel@tonic-gate } 1232*7c478bd9Sstevel@tonic-gate sprintf(pkeyatval, "{%s}%s", mechname, public); 1233*7c478bd9Sstevel@tonic-gate ckeyatval = (char *)malloc(strlen(mechname) + strlen(crypt) + 3); 1234*7c478bd9Sstevel@tonic-gate if (ckeyatval == NULL) { 1235*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1236*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1237*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1238*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP memory error (pkeyatval)\n"); 1239*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", program_name); 1240*7c478bd9Sstevel@tonic-gate exit(1); 1241*7c478bd9Sstevel@tonic-gate } 1242*7c478bd9Sstevel@tonic-gate sprintf(ckeyatval, "{%s}%s", mechname, crypt); 1243*7c478bd9Sstevel@tonic-gate 1244*7c478bd9Sstevel@tonic-gate /* Does entry exist? */ 1245*7c478bd9Sstevel@tonic-gate if ((__ns_ldap_list(db, filter, NULL, (const char **)attrFilter, 1246*7c478bd9Sstevel@tonic-gate NULL, 0, &res, &errorp, 1247*7c478bd9Sstevel@tonic-gate NULL, NULL) == NS_LDAP_SUCCESS) && res == NULL) { 1248*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(ckeyatval); 1249*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1250*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1251*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1252*7c478bd9Sstevel@tonic-gate fprintf(stderr, "LDAP entry does not exist.\n"); 1253*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", program_name); 1254*7c478bd9Sstevel@tonic-gate exit(1); 1255*7c478bd9Sstevel@tonic-gate } 1256*7c478bd9Sstevel@tonic-gate 1257*7c478bd9Sstevel@tonic-gate /* Entry exists, modify attributes for public and secret keys */ 1258*7c478bd9Sstevel@tonic-gate 1259*7c478bd9Sstevel@tonic-gate /* Is there a NisKeyObject in entry? */ 1260*7c478bd9Sstevel@tonic-gate if (!ldap_keyobj_exist(&res->entry[0])) { 1261*7c478bd9Sstevel@tonic-gate /* Add NisKeyObject objectclass and the keys */ 1262*7c478bd9Sstevel@tonic-gate char **newattr; 1263*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t *attrs[4]; /* objectclass, pk, sk, NULL */ 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate /* set objectclass */ 1266*7c478bd9Sstevel@tonic-gate newattr = (char **)calloc(2, sizeof (char *)); 1267*7c478bd9Sstevel@tonic-gate newattr[0] = "NisKeyObject"; 1268*7c478bd9Sstevel@tonic-gate newattr[1] = NULL; 1269*7c478bd9Sstevel@tonic-gate if ((attrs[0] = (ns_ldap_attr_t *)calloc(1, 1270*7c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t))) == NULL) { 1271*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(ckeyatval); 1272*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1273*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1274*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1275*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Memory allocation failed\n"); 1276*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1277*7c478bd9Sstevel@tonic-gate program_name); 1278*7c478bd9Sstevel@tonic-gate exit(1); 1279*7c478bd9Sstevel@tonic-gate } 1280*7c478bd9Sstevel@tonic-gate attrs[0]->attrname = "objectClass"; 1281*7c478bd9Sstevel@tonic-gate attrs[0]->attrvalue = newattr; 1282*7c478bd9Sstevel@tonic-gate attrs[0]->value_count = 1; 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate /* set publickey */ 1285*7c478bd9Sstevel@tonic-gate newattr = (char **)calloc(2, sizeof (char *)); 1286*7c478bd9Sstevel@tonic-gate newattr[0] = pkeyatval; 1287*7c478bd9Sstevel@tonic-gate newattr[1] = NULL; 1288*7c478bd9Sstevel@tonic-gate if ((attrs[1] = (ns_ldap_attr_t *)calloc(1, 1289*7c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t))) == NULL) { 1290*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(ckeyatval); 1291*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1292*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1293*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1294*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Memory allocation failed\n"); 1295*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1296*7c478bd9Sstevel@tonic-gate program_name); 1297*7c478bd9Sstevel@tonic-gate exit(1); 1298*7c478bd9Sstevel@tonic-gate } 1299*7c478bd9Sstevel@tonic-gate attrs[1]->attrname = "nisPublicKey"; 1300*7c478bd9Sstevel@tonic-gate attrs[1]->attrvalue = newattr; 1301*7c478bd9Sstevel@tonic-gate attrs[1]->value_count = 1; 1302*7c478bd9Sstevel@tonic-gate 1303*7c478bd9Sstevel@tonic-gate /* set privatekey */ 1304*7c478bd9Sstevel@tonic-gate newattr = (char **)calloc(2, sizeof (char *)); 1305*7c478bd9Sstevel@tonic-gate newattr[0] = ckeyatval; 1306*7c478bd9Sstevel@tonic-gate newattr[1] = NULL; 1307*7c478bd9Sstevel@tonic-gate if ((attrs[2] = (ns_ldap_attr_t *)calloc(1, 1308*7c478bd9Sstevel@tonic-gate sizeof (ns_ldap_attr_t))) == NULL) { 1309*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(ckeyatval); 1310*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1311*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1312*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1313*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Memory allocation failed\n"); 1314*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: key-pair(s) unchanged.\n", 1315*7c478bd9Sstevel@tonic-gate program_name); 1316*7c478bd9Sstevel@tonic-gate exit(1); 1317*7c478bd9Sstevel@tonic-gate } 1318*7c478bd9Sstevel@tonic-gate attrs[2]->attrname = "nisSecretKey"; 1319*7c478bd9Sstevel@tonic-gate attrs[2]->attrvalue = newattr; 1320*7c478bd9Sstevel@tonic-gate attrs[2]->value_count = 1; 1321*7c478bd9Sstevel@tonic-gate 1322*7c478bd9Sstevel@tonic-gate /* terminator */ 1323*7c478bd9Sstevel@tonic-gate attrs[3] = NULL; 1324*7c478bd9Sstevel@tonic-gate 1325*7c478bd9Sstevel@tonic-gate update_ldap_attr(dn, attrs, passwd, TRUE, update4host, 1326*7c478bd9Sstevel@tonic-gate bindDN, bindPasswd); 1327*7c478bd9Sstevel@tonic-gate } else { 1328*7c478bd9Sstevel@tonic-gate /* object class already exists, replace keys */ 1329*7c478bd9Sstevel@tonic-gate ns_ldap_attr_t *attrs[4]; /* objectclass, pk, sk, NULL */ 1330*7c478bd9Sstevel@tonic-gate 1331*7c478bd9Sstevel@tonic-gate if (!ldap_attr_mod(&res->entry[0], mechname, 1332*7c478bd9Sstevel@tonic-gate pkeyatval, &pattrs, 1333*7c478bd9Sstevel@tonic-gate ckeyatval, &cattrs)) { 1334*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(ckeyatval); 1335*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1336*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1337*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1338*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1339*7c478bd9Sstevel@tonic-gate "Could not generate LDAP attribute list.\n"); 1340*7c478bd9Sstevel@tonic-gate fprintf(stderr, 1341*7c478bd9Sstevel@tonic-gate "%s: key-pair(s) unchanged.\n", program_name); 1342*7c478bd9Sstevel@tonic-gate exit(1); 1343*7c478bd9Sstevel@tonic-gate } 1344*7c478bd9Sstevel@tonic-gate 1345*7c478bd9Sstevel@tonic-gate attrs[0] = pattrs; 1346*7c478bd9Sstevel@tonic-gate attrs[1] = cattrs; 1347*7c478bd9Sstevel@tonic-gate attrs[2] = NULL; 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate update_ldap_attr(dn, attrs, passwd, FALSE, update4host, 1350*7c478bd9Sstevel@tonic-gate bindDN, bindPasswd); 1351*7c478bd9Sstevel@tonic-gate } 1352*7c478bd9Sstevel@tonic-gate 1353*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(ckeyatval); 1354*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(pkeyatval); 1355*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindPasswd); 1356*7c478bd9Sstevel@tonic-gate FREE_CREDINFO(bindDN); 1357*7c478bd9Sstevel@tonic-gate 1358*7c478bd9Sstevel@tonic-gate return (0); 1359*7c478bd9Sstevel@tonic-gate } 1360*7c478bd9Sstevel@tonic-gate 1361*7c478bd9Sstevel@tonic-gate 1362*7c478bd9Sstevel@tonic-gate /* Returns 0 if successful; -1 if failure. (expected by setpublicmap). */ 1363*7c478bd9Sstevel@tonic-gate 1364*7c478bd9Sstevel@tonic-gate int 1365*7c478bd9Sstevel@tonic-gate nisplus_update(char *netname, char *public, char *secret, nis_name nis_princ) 1366*7c478bd9Sstevel@tonic-gate { 1367*7c478bd9Sstevel@tonic-gate nis_object *obj = init_entry(); 1368*7c478bd9Sstevel@tonic-gate char *domain, *netdomain; 1369*7c478bd9Sstevel@tonic-gate char netdomainaux[MAXHOSTNAMELEN + 1]; 1370*7c478bd9Sstevel@tonic-gate int status, addition; 1371*7c478bd9Sstevel@tonic-gate 1372*7c478bd9Sstevel@tonic-gate /* 1373*7c478bd9Sstevel@tonic-gate * we take the domain given in the netname & the principal 1374*7c478bd9Sstevel@tonic-gate * name if they match otherwise the local domain. 1375*7c478bd9Sstevel@tonic-gate */ 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate netdomain = (char *)strchr(netname, '@'); 1378*7c478bd9Sstevel@tonic-gate if (! netdomain) { 1379*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: invalid netname: '%s'. \n", 1380*7c478bd9Sstevel@tonic-gate program_name, netname); 1381*7c478bd9Sstevel@tonic-gate return (0); 1382*7c478bd9Sstevel@tonic-gate } 1383*7c478bd9Sstevel@tonic-gate netdomain++; /* skip '@' */ 1384*7c478bd9Sstevel@tonic-gate /* make sure we don't run into buffer overflow */ 1385*7c478bd9Sstevel@tonic-gate if (strlen(netdomain) > sizeof (netdomainaux)) 1386*7c478bd9Sstevel@tonic-gate return (0); 1387*7c478bd9Sstevel@tonic-gate strcpy(netdomainaux, netdomain); 1388*7c478bd9Sstevel@tonic-gate if (netdomainaux[strlen(netdomainaux) - 1] != '.') 1389*7c478bd9Sstevel@tonic-gate strcat(netdomainaux, "."); 1390*7c478bd9Sstevel@tonic-gate 1391*7c478bd9Sstevel@tonic-gate domain = nis_domain_of(nis_princ); 1392*7c478bd9Sstevel@tonic-gate if (strcasecmp(domain, netdomainaux) != 0) 1393*7c478bd9Sstevel@tonic-gate domain = nis_local_directory(); 1394*7c478bd9Sstevel@tonic-gate 1395*7c478bd9Sstevel@tonic-gate if (sanity_checks(nis_princ, netname, domain) == 0) 1396*7c478bd9Sstevel@tonic-gate return (-1); 1397*7c478bd9Sstevel@tonic-gate 1398*7c478bd9Sstevel@tonic-gate addition = (cred_exists(nis_princ, "DES", domain) == NIS_NOTFOUND); 1399*7c478bd9Sstevel@tonic-gate 1400*7c478bd9Sstevel@tonic-gate /* Now we have a key pair, build up the cred entry */ 1401*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 0) = nis_princ; 1402*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 0) = strlen(nis_princ) + 1; 1403*7c478bd9Sstevel@tonic-gate 1404*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 1) = "DES"; 1405*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 1) = 4; 1406*7c478bd9Sstevel@tonic-gate 1407*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 2) = netname; 1408*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 2) = strlen(netname) + 1; 1409*7c478bd9Sstevel@tonic-gate 1410*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 3) = public; 1411*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 3) = strlen(public) + 1; 1412*7c478bd9Sstevel@tonic-gate 1413*7c478bd9Sstevel@tonic-gate ENTRY_VAL(obj, 4) = secret; 1414*7c478bd9Sstevel@tonic-gate ENTRY_LEN(obj, 4) = strlen(secret) + 1; 1415*7c478bd9Sstevel@tonic-gate 1416*7c478bd9Sstevel@tonic-gate if (addition) { 1417*7c478bd9Sstevel@tonic-gate obj->zo_owner = nis_princ; 1418*7c478bd9Sstevel@tonic-gate obj->zo_group = nis_local_group(); 1419*7c478bd9Sstevel@tonic-gate obj->zo_domain = domain; 1420*7c478bd9Sstevel@tonic-gate /* owner: r, group: rmcd */ 1421*7c478bd9Sstevel@tonic-gate obj->zo_access = ((NIS_READ_ACC<<16)| 1422*7c478bd9Sstevel@tonic-gate (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC| 1423*7c478bd9Sstevel@tonic-gate NIS_DESTROY_ACC)<<8); 1424*7c478bd9Sstevel@tonic-gate status = add_cred_obj(obj, domain); 1425*7c478bd9Sstevel@tonic-gate } else { 1426*7c478bd9Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val[3].ec_flags |= EN_MODIFIED; 1427*7c478bd9Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val[4].ec_flags |= EN_MODIFIED; 1428*7c478bd9Sstevel@tonic-gate status = modify_cred_obj(obj, domain); 1429*7c478bd9Sstevel@tonic-gate } 1430*7c478bd9Sstevel@tonic-gate 1431*7c478bd9Sstevel@tonic-gate return (status == 1 ? 0 : -1); 1432*7c478bd9Sstevel@tonic-gate } 1433