static int winbind_open_pipe_sock(int recursing) { #ifdef HAVE_UNIXSOCKET static pid_t our_pid; struct winbindd_request request; struct winbindd_response response; ZERO_STRUCT(request); ZERO_STRUCT(response); if (our_pid != getpid()) { close_sock(); our_pid = getpid(); } if (winbindd_fd != -1) { return winbindd_fd; } if (recursing) { return -1; } if ((winbindd_fd = winbind_named_pipe_sock(WINBINDD_SOCKET_DIR)) == -1) { return -1; } /* version-check the socket */ request.flags = WBFLAG_RECURSE; if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { close_sock(); return -1; } /* try and get priv pipe */ request.flags = WBFLAG_RECURSE; if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) { int fd; if ((fd = winbind_named_pipe_sock(response.extra_data.data)) != -1) { close(winbindd_fd); winbindd_fd = fd; } } SAFE_FREE(response.extra_data.data); return winbindd_fd; #else return -1; #endif /* HAVE_UNIXSOCKET */ }
static bool print_domain_groups(const char *domain) { struct winbindd_request request; struct winbindd_response response; const char *extra_data; fstring name; ZERO_STRUCT(request); ZERO_STRUCT(response); if (domain) { if ( strequal(domain, ".") ) fstrcpy( request.domain_name, get_winbind_domain() ); else fstrcpy( request.domain_name, domain ); } if (winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response) != NSS_STATUS_SUCCESS) return false; /* Look through extra data */ if (!response.extra_data.data) return false; extra_data = (const char *)response.extra_data.data; while(next_token(&extra_data, name, ",", sizeof(fstring))) d_printf("%s\n", name); SAFE_FREE(response.extra_data.data); return true; }
/* show sequence numbers */ static bool wbinfo_show_sequence(const char *domain) { struct winbindd_request request; struct winbindd_response response; ZERO_STRUCT(response); ZERO_STRUCT(request); if ( domain ) fstrcpy( request.domain_name, domain ); /* Send request */ if (winbindd_request_response(WINBINDD_SHOW_SEQUENCE, &request, &response) != NSS_STATUS_SUCCESS) return false; /* Display response */ if (response.extra_data.data) { char *extra_data = (char *)response.extra_data.data; d_printf("%s", extra_data); SAFE_FREE(response.extra_data.data); } return true; }
/* List group SIDs a user SID is a member of */ static bool wbinfo_get_usersids(char *user_sid) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; int i; const char *s; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send request */ fstrcpy(request.data.sid, user_sid); result = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); if (result != NSS_STATUS_SUCCESS) return false; s = (const char *)response.extra_data.data; for (i = 0; i < response.data.num_entries; i++) { d_printf("%s\n", s); s += strlen(s) + 1; } SAFE_FREE(response.extra_data.data); return true; }
static bool wbinfo_get_userdomgroups(const char *user_sid) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send request */ fstrcpy(request.data.sid, user_sid); result = winbindd_request_response(WINBINDD_GETUSERDOMGROUPS, &request, &response); if (result != NSS_STATUS_SUCCESS) return false; if (response.data.num_entries != 0) printf("%s", (char *)response.extra_data.data); SAFE_FREE(response.extra_data.data); return true; }
/* pull grent for a given gid */ static bool wbinfo_get_gidinfo(int gid) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send request */ request.data.gid = gid; result = winbindd_request_response(WINBINDD_GETGRGID, &request, &response); if ( result != NSS_STATUS_SUCCESS) return false; d_printf( "%s:%s:%d\n", response.data.gr.gr_name, response.data.gr.gr_passwd, response.data.gr.gr_gid ); return true; }
static bool wbinfo_get_usergroups(char *user) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; int i; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send request */ fstrcpy(request.data.username, user); result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); if (result != NSS_STATUS_SUCCESS) return false; for (i = 0; i < response.data.num_entries; i++) d_printf("%d\n", (int)((gid_t *)response.extra_data.data)[i]); SAFE_FREE(response.extra_data.data); return true; }
/* pull grent for a given group */ static bool wbinfo_get_groupinfo(char *group) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send request */ fstrcpy(request.data.groupname, group); result = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response); if ( result != NSS_STATUS_SUCCESS) return false; d_printf( "%s:%s:%d\n", response.data.gr.gr_name, response.data.gr.gr_passwd, response.data.gr.gr_gid ); return true; }
/* pull pwent info for a given uid */ static bool wbinfo_get_uidinfo(int uid) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; ZERO_STRUCT(request); ZERO_STRUCT(response); request.data.uid = uid; result = winbindd_request_response(WINBINDD_GETPWUID, &request, &response); if (result != NSS_STATUS_SUCCESS) return false; d_printf( "%s:%s:%d:%d:%s:%s:%s\n", response.data.pw.pw_name, response.data.pw.pw_passwd, response.data.pw.pw_uid, response.data.pw.pw_gid, response.data.pw.pw_gecos, response.data.pw.pw_dir, response.data.pw.pw_shell ); return true; }
static bool wbinfo_get_userinfo(char *user) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send request */ fstrcpy(request.data.username, user); result = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response); if (result != NSS_STATUS_SUCCESS) return false; d_printf( "%s:%s:%d:%d:%s:%s:%s\n", response.data.pw.pw_name, response.data.pw.pw_passwd, response.data.pw.pw_uid, response.data.pw.pw_gid, response.data.pw.pw_gecos, response.data.pw.pw_dir, response.data.pw.pw_shell ); return true; }
wbcErr wbcRequestResponse(int cmd, struct winbindd_request *request, struct winbindd_response *response) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; NSS_STATUS nss_status; /* for some calls the request and/or response cna be NULL */ nss_status = winbindd_request_response(cmd, request, response); switch (nss_status) { case NSS_STATUS_SUCCESS: wbc_status = WBC_ERR_SUCCESS; break; case NSS_STATUS_UNAVAIL: wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE; break; case NSS_STATUS_NOTFOUND: wbc_status = WBC_ERR_DOMAIN_NOT_FOUND; break; default: wbc_status = WBC_ERR_NSS_ERROR; break; } return wbc_status; }
/* Find a DC */ static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags) { struct winbindd_request request; struct winbindd_response response; ZERO_STRUCT(request); ZERO_STRUCT(response); fstrcpy(request.domain_name, domain_name); request.flags = flags; request.flags |= DS_DIRECTORY_SERVICE_REQUIRED; /* Send request */ if (winbindd_request_response(WINBINDD_DSGETDCNAME, &request, &response) != NSS_STATUS_SUCCESS) { d_fprintf(stderr, "Could not find dc for %s\n", domain_name); return false; } /* Display response */ d_printf("%s\n", response.data.dc_name); return true; }
/* map a sid to a gid */ NSS_STATUS _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop) { NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request; #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: sidtogid %s\n", getpid(), sid); #endif ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.sid, sid, sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } *gid = response.data.gid; failed: return ret; }
/* take a uid and return a filled struct passwd */ static struct passwd *wb_aix_getpwuid(uid_t uid) { struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; struct passwd *pwd; logit("getpwuid '%d'\n", uid); ZERO_STRUCT(response); ZERO_STRUCT(request); request.data.uid = uid; ret = winbindd_request_response(NULL, WINBINDD_GETPWUID, &request, &response); HANDLE_ERRORS(ret); pwd = fill_pwent(&response.data.pw); winbindd_free_response(&response); logit("getpwuid gave ptr %p\n", pwd); return pwd; }
/* take a group name and return a filled struct group */ static struct group *wb_aix_getgrnam(const char *name) { struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; struct group *grp; if (*name == WB_AIX_ENCODED) { return wb_aix_getgrgid(decode_id(name)); } logit("getgrnam '%s'\n", name); ZERO_STRUCT(response); ZERO_STRUCT(request); STRCPY_RETNULL(request.data.groupname, name); ret = winbindd_request_response(NULL, WINBINDD_GETGRNAM, &request, &response); HANDLE_ERRORS(ret); grp = fill_grent(&response.data.gr, response.extra_data.data); winbindd_free_response(&response); return grp; }
NSS_STATUS _nss_winbind_endgrent(void) { NSS_STATUS ret; #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: endgrent\n", getpid()); #endif #if HAVE_PTHREAD pthread_mutex_lock(&winbind_nss_mutex); #endif if (num_gr_cache > 0) { ndx_gr_cache = num_gr_cache = 0; winbindd_free_response(&getgrent_response); } ret = winbindd_request_response(NULL, WINBINDD_ENDGRENT, NULL, NULL); #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: endgrent returns %s (%d)\n", getpid(), nss_err_str(ret), ret); #endif #if HAVE_PTHREAD pthread_mutex_unlock(&winbind_nss_mutex); #endif return ret; }
static char winbind_separator(void) { struct winbindd_response response; static BOOL got_sep; static char sep; if (got_sep) return sep; ZERO_STRUCT(response); /* Send off request */ if (winbindd_request_response(WINBINDD_INFO, NULL, &response) != NSS_STATUS_SUCCESS) { d_printf("could not obtain winbind separator!\n"); return *lp_winbind_separator(); } sep = response.data.info.winbind_separator; got_sep = True; if (!sep) { d_printf("winbind separator was NULL!\n"); return *lp_winbind_separator(); } return sep; }
static bool ask_winbind(const char *realm, char **dcname) { NSS_STATUS status; struct winbindd_request request; struct winbindd_response response; ZERO_STRUCT(request); ZERO_STRUCT(response); request.flags = 0x40020600; /* DS_KDC_REQUIRED | DS_IS_DNS_NAME | DS_RETURN_DNS_NAME | DS_IP_REQUIRED */ strncpy(request.domain_name, realm, sizeof(request.domain_name)-1); status = winbindd_request_response(WINBINDD_DSGETDCNAME, &request, &response); if (status != NSS_STATUS_SUCCESS) { #ifdef DEBUG_KRB5 fprintf(stderr,"[%5u]: smb_krb5_locator_lookup: failed with: %s\n", (unsigned int)getpid(), nss_err_str(status)); #endif return false; } *dcname = strdup(response.data.dc_name); if (!*dcname) { return false; } return true; }
const char *get_winbind_netbios_name(void) { struct winbindd_response response; static fstring winbind_netbios_name; if (*winbind_netbios_name) { return winbind_netbios_name; } ZERO_STRUCT(response); /* Send off request */ if (winbindd_request_response(WINBINDD_NETBIOS_NAME, NULL, &response) != NSS_STATUS_SUCCESS) { DEBUG(0, ("could not obtain winbind netbios name!\n")); return global_myname(); } fstrcpy(winbind_netbios_name, response.data.netbios_name); return winbind_netbios_name; }
/* take a username and return a filled struct passwd */ static struct passwd *wb_aix_getpwnam(const char *name) { struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; struct passwd *pwd; if (*name == WB_AIX_ENCODED) { return wb_aix_getpwuid(decode_id(name)); } logit("getpwnam '%s'\n", name); ZERO_STRUCT(response); ZERO_STRUCT(request); STRCPY_RETNULL(request.data.username, name); ret = winbindd_request_response(NULL, WINBINDD_GETPWNAM, &request, &response); HANDLE_ERRORS(ret); pwd = fill_pwent(&response.data.pw); winbindd_free_response(&response); logit("getpwnam gave ptr %p\n", pwd); return pwd; }
/* take a group id and return a filled struct group */ static struct group *wb_aix_getgrgid(gid_t gid) { struct winbindd_response response; struct winbindd_request request; struct group *grp; NSS_STATUS ret; logit("getgrgid %d\n", gid); ZERO_STRUCT(response); ZERO_STRUCT(request); request.data.gid = gid; ret = winbindd_request_response(NULL, WINBINDD_GETGRGID, &request, &response); logit("getgrgid ret=%d\n", ret); HANDLE_ERRORS(ret); grp = fill_grent(&response.data.gr, response.extra_data.data); winbindd_free_response(&response); return grp; }
static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; char *p; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); p = strchr(username, '%'); if (p) { *p = 0; fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, p + 1); *p = '%'; } else fstrcpy(request.data.auth.user, username); request.flags = flags; fstrcpy(request.data.auth.krb5_cc_type, cctype); request.data.auth.uid = geteuid(); result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); /* Display response */ d_printf("plaintext kerberos password authentication for [%s] %s (requesting cctype: %s)\n", username, (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", cctype); if (response.data.auth.nt_status) d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); if (result == NSS_STATUS_SUCCESS) { if (request.flags & WBFLAG_PAM_INFO3_TEXT) { if (response.data.auth.info3.user_flgs & NETLOGON_CACHED_ACCOUNT) { d_printf("user_flgs: NETLOGON_CACHED_ACCOUNT\n"); } } if (response.data.auth.krb5ccname[0] != '\0') { d_printf("credentials were put in: %s\n", response.data.auth.krb5ccname); } else { d_printf("no credentials cached\n"); } } return result == NSS_STATUS_SUCCESS; }
static bool wbinfo_klog(char *username) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; char *p; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); p = strchr(username, '%'); if (p) { *p = 0; fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, p + 1); *p = '%'; } else { fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, getpass("Password: "******"plaintext password authentication %s\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); if (response.data.auth.nt_status) d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", response.data.auth.nt_status_string, response.data.auth.nt_status, response.data.auth.error_string); if (result != NSS_STATUS_SUCCESS) return false; if (response.extra_data.data == NULL) { d_fprintf(stderr, "Did not get token data\n"); return false; } if (!afs_settoken_str((char *)response.extra_data.data)) { d_fprintf(stderr, "Could not set token\n"); return false; } d_printf("Successfully created AFS token\n"); return true; }
/* take a username and return a string containing a comma-separated list of group id numbers to which the user belongs */ static char *wb_aix_getgrset(char *user) { struct winbindd_response response; struct winbindd_request request; NSS_STATUS ret; int i, idx; char *tmpbuf; int num_gids; gid_t *gid_list; char *r_user = user; if (*user == WB_AIX_ENCODED) { r_user = decode_user(r_user); if (!r_user) { errno = ENOENT; return NULL; } } logit("getgrset '%s'\n", r_user); ZERO_STRUCT(response); ZERO_STRUCT(request); STRCPY_RETNULL(request.data.username, r_user); if (*user == WB_AIX_ENCODED) { free(r_user); } ret = winbindd_request_response(NULL, WINBINDD_GETGROUPS, &request, &response); HANDLE_ERRORS(ret); num_gids = response.data.num_entries; gid_list = (gid_t *)response.extra_data.data; /* allocate a space large enough to contruct the string */ tmpbuf = malloc(num_gids*12); if (!tmpbuf) { return NULL; } for (idx=i=0; i < num_gids-1; i++) { idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]); } idx += sprintf(tmpbuf+idx, "%u", gid_list[i]); winbindd_free_response(&response); return tmpbuf; }
static bool wbinfo_ping(void) { NSS_STATUS result; result = winbindd_request_response(WINBINDD_PING, NULL, NULL); /* Display response */ d_printf("Ping to winbindd %s on fd %d\n", (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd); return result == NSS_STATUS_SUCCESS; }
/* return a list of group SIDs for a user SID */ NSS_STATUS _nss_winbind_getusersids(const char *user_sid, char **group_sids, int *num_groups, char *buffer, size_t buf_size, int *errnop) { NSS_STATUS ret; struct winbindd_request request; struct winbindd_response response; #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid); #endif #if HAVE_PTHREAD pthread_mutex_lock(&winbind_nss_mutex); #endif ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1); request.data.sid[sizeof(request.data.sid) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response); if (ret != NSS_STATUS_SUCCESS) { goto done; } if (buf_size < response.length - sizeof(response)) { ret = NSS_STATUS_TRYAGAIN; errno = *errnop = ERANGE; goto done; } *num_groups = response.data.num_entries; *group_sids = buffer; memcpy(buffer, response.extra_data.data, response.length - sizeof(response)); errno = *errnop = 0; done: winbindd_free_response(&response); #if HAVE_PTHREAD pthread_mutex_unlock(&winbind_nss_mutex); #endif return ret; }
/* map a user or group name to a SID string */ NSS_STATUS _nss_winbind_nametosid(const char *name, char **sid, char *buffer, size_t buflen, int *errnop) { NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request; #ifdef DEBUG_NSS fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name); #endif #if HAVE_PTHREAD pthread_mutex_lock(&winbind_nss_mutex); #endif ZERO_STRUCT(response); ZERO_STRUCT(request); strncpy(request.data.name.name, name, sizeof(request.data.name.name) - 1); request.data.name.name[sizeof(request.data.name.name) - 1] = '\0'; ret = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } if (buflen < strlen(response.data.sid.sid)+1) { ret = NSS_STATUS_TRYAGAIN; *errnop = errno = ERANGE; goto failed; } *errnop = errno = 0; *sid = buffer; strcpy(*sid, response.data.sid.sid); failed: winbindd_free_response(&response); #if HAVE_PTHREAD pthread_mutex_unlock(&winbind_nss_mutex); #endif return ret; }
static BOOL check_plaintext_auth(const char *user, const char *pass, BOOL stdout_diagnostics) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; if (!get_require_membership_sid()) { return False; } /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); fstrcpy(request.data.auth.user, user); fstrcpy(request.data.auth.pass, pass); if (require_membership_of_sid) fstrcpy(request.data.auth.require_membership_of_sid, require_membership_of_sid); result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response); /* Display response */ if (stdout_diagnostics) { if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) { d_printf("Reading winbind reply failed! (0x01)\n"); } d_printf("%s: %s (0x%x)\n", response.data.auth.nt_status_string, response.data.auth.error_string, response.data.auth.nt_status); } else { if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) { DEBUG(1, ("Reading winbind reply failed! (0x01)\n")); } DEBUG(3, ("%s: %s (0x%x)\n", response.data.auth.nt_status_string, response.data.auth.error_string, response.data.auth.nt_status)); } return (result == NSS_STATUS_SUCCESS); }
/* map a gid to a SID string */ NSS_STATUS _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer, size_t buflen, int *errnop) { NSS_STATUS ret; struct winbindd_response response; struct winbindd_request request; #ifdef DEBUG_NSS fprintf(stderr, "[%5u]: gidtosid %u\n", (unsigned int)getpid(), (unsigned int)gid); #endif #if HAVE_PTHREAD pthread_mutex_lock(&winbind_nss_mutex); #endif ZERO_STRUCT(response); ZERO_STRUCT(request); request.data.gid = gid; ret = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response); if (ret != NSS_STATUS_SUCCESS) { *errnop = errno = EINVAL; goto failed; } if (buflen < strlen(response.data.sid.sid)+1) { ret = NSS_STATUS_TRYAGAIN; *errnop = errno = ERANGE; goto failed; } *errnop = errno = 0; *sid = buffer; strcpy(*sid, response.data.sid.sid); failed: winbindd_free_response(&response); #if HAVE_PTHREAD pthread_mutex_unlock(&winbind_nss_mutex); #endif return ret; }
/* authenticate a user */ static int wb_aix_authenticate(char *user, char *pass, int *reenter, char **message) { struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; char *r_user = user; logit("authenticate '%s' response='%s'\n", user, pass); *reenter = 0; *message = NULL; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); if (*user == WB_AIX_ENCODED) { r_user = decode_user(r_user); if (!r_user) { return AUTH_NOTFOUND; } } STRCPY_RET(request.data.auth.user, r_user); STRCPY_RET(request.data.auth.pass, pass); if (*user == WB_AIX_ENCODED) { free(r_user); } result = winbindd_request_response(NULL, WINBINDD_PAM_AUTH, &request, &response); winbindd_free_response(&response); logit("auth result %d for '%s'\n", result, user); if (result == NSS_STATUS_SUCCESS) { errno = 0; return AUTH_SUCCESS; } return AUTH_FAILURE; }