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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <shadow.h> 26 #include <stdlib.h> 27 #include "ad_common.h" 28 29 static int 30 update_buffer(ad_backend_ptr be, nss_XbyY_args_t *argp, 31 const char *name, const char *domain) 32 { 33 int buflen; 34 char *buffer; 35 36 /* 37 * The user password is not available in the AD object and therefore 38 * sp_pwdp will be "*NP*". 39 * 40 * nss_ad will leave aging fields empty (i.e. The front end 41 * marshaller will set sp_lstchgst, sp_min, sp_max, sp_warn, 42 * sp_inact, and sp_expire to -1 and sp_flag to 0) because shadow 43 * fields are irrevalent with AD and krb5. 44 */ 45 46 buflen = snprintf(NULL, 0, "%s@%s:*NP*:::::::", name, domain) + 1; 47 48 if (argp->buf.result != NULL) { 49 buffer = be->buffer = malloc(buflen); 50 if (be->buffer == NULL) 51 return (-1); 52 be->buflen = buflen; 53 } else { 54 if (buflen > argp->buf.buflen) 55 return (-1); 56 buflen = argp->buf.buflen; 57 buffer = argp->buf.buffer; 58 } 59 60 buflen = snprintf(buffer, buflen, "%s@%s:*NP*:::::::", 61 name, domain) + 1; 62 return (0); 63 } 64 65 /* 66 * getbynam gets a shadow entry by winname. This function constructs an ldap 67 * search filter using the name invocation parameter and the getspnam search 68 * filter defined. Once the filter is constructed we search for a matching 69 * entry and marshal the data results into struct shadow for the frontend 70 * process. The function _nss_ad_shadow2ent performs the data marshaling. 71 */ 72 static nss_status_t 73 getbynam(ad_backend_ptr be, void *a) 74 { 75 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 76 char name[SEARCHFILTERLEN + 1]; 77 char *dname; 78 nss_status_t stat; 79 idmap_stat idmaprc; 80 uid_t uid; 81 int is_user, is_wuser; 82 83 be->db_type = NSS_AD_DB_SHADOW_BYNAME; 84 85 /* Sanitize name so that it can be used in our LDAP filter */ 86 if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) 87 return ((nss_status_t)NSS_NOTFOUND); 88 89 if ((dname = strchr(name, '@')) == NULL) 90 return ((nss_status_t)NSS_NOTFOUND); 91 92 *dname = '\0'; 93 dname++; 94 95 /* 96 * Use idmap service to verify that the given 97 * name is a valid Windows name. 98 */ 99 is_wuser = -1; 100 is_user = 1; 101 idmaprc = idmap_get_w2u_mapping(NULL, NULL, name, dname, 102 0, &is_user, &is_wuser, &uid, NULL, NULL, NULL); 103 if (idmaprc != IDMAP_SUCCESS) { 104 RESET_ERRNO(); 105 return ((nss_status_t)NSS_NOTFOUND); 106 } 107 108 /* Create shadow(5) style string */ 109 if (update_buffer(be, argp, name, dname) < 0) 110 return ((nss_status_t)NSS_NOTFOUND); 111 112 /* Marshall the data, sanitize the return status and return */ 113 stat = _nss_ad_marshall_data(be, argp); 114 return (_nss_ad_sanitize_status(be, argp, stat)); 115 } 116 117 static ad_backend_op_t sp_ops[] = { 118 _nss_ad_destr, 119 _nss_ad_endent, 120 _nss_ad_setent, 121 _nss_ad_getent, 122 getbynam 123 }; 124 125 126 /* 127 * _nss_ad_passwd_constr is where life begins. This function calls the 128 * generic ldap constructor function to define and build the abstract 129 * data types required to support ldap operations. 130 */ 131 /*ARGSUSED0*/ 132 nss_backend_t * 133 _nss_ad_shadow_constr(const char *dummy1, const char *dummy2, 134 const char *dummy3) 135 { 136 137 return ((nss_backend_t *)_nss_ad_constr(sp_ops, 138 sizeof (sp_ops)/sizeof (sp_ops[0]), 139 _SHADOW, NULL, NULL)); 140 } 141