diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 30 | ||||
-rw-r--r-- | source3/nsswitch/wb_client.c | 110 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 106 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.c | 1 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.h | 9 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 1 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_async.c | 173 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cache.c | 136 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 2 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_dual.c | 1 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_nss.h | 3 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_passdb.c | 64 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_reconnect.c | 25 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 56 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_sid.c | 40 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 18 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 2 |
17 files changed, 670 insertions, 107 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 78776256e9..118ba358e1 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -128,6 +128,24 @@ static void _pam_winbind_cleanup_func(pam_handle_t *pamh, void *data, int error_ SAFE_FREE(data); } +/* + * Work around the pam API that has functions with void ** as parameters. + * These lead to strict aliasing warnings with gcc. + */ +static int _pam_get_item(const pam_handle_t *pamh, int item_type, + const void *_item) +{ + const void **item = (const void **)_item; + return pam_get_item(pamh, item_type, item); +} +static int _pam_get_data(const pam_handle_t *pamh, + const char *module_data_name, const void *_data) +{ + const void **data = (const void **)_data; + return pam_get_data(pamh, module_data_name, data); +} + + static const struct ntstatus_errors { const char *ntstatus_string; const char *error_string; @@ -173,7 +191,7 @@ static int converse(pam_handle_t *pamh, int nargs, int retval; struct pam_conv *conv; - retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ); + retval = _pam_get_item(pamh, PAM_CONV, &conv ); if (retval == PAM_SUCCESS) { retval = conv->conv(nargs, (const struct pam_message **)message, response, conv->appdata_ptr); @@ -676,7 +694,7 @@ static int _winbind_read_password(pam_handle_t * pamh, */ if (on(WINBIND_TRY_FIRST_PASS_ARG, ctrl) || on(WINBIND_USE_FIRST_PASS_ARG, ctrl)) { - retval = pam_get_item(pamh, authtok_flag, (const void **) &item); + retval = _pam_get_item(pamh, authtok_flag, &item); if (retval != PAM_SUCCESS) { /* very strange. */ _pam_log(LOG_ALERT, @@ -778,7 +796,7 @@ static int _winbind_read_password(pam_handle_t * pamh, retval = pam_set_item(pamh, authtok_flag, token); _pam_delete(token); /* clean it up */ if (retval != PAM_SUCCESS || - (retval = pam_get_item(pamh, authtok_flag, (const void **) &item)) != PAM_SUCCESS) { + (retval = _pam_get_item(pamh, authtok_flag, &item)) != PAM_SUCCESS) { _pam_log(LOG_CRIT, "error manipulating password"); return retval; @@ -1251,8 +1269,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, * get the old token back. */ - retval = pam_get_item(pamh, PAM_OLDAUTHTOK, - (const void **) &pass_old); + retval = _pam_get_item(pamh, PAM_OLDAUTHTOK, &pass_old); if (retval != PAM_SUCCESS) { _pam_log(LOG_NOTICE, "user not authenticated"); @@ -1300,7 +1317,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, * By reaching here we have approved the passwords and must now * rebuild the password database file. */ - pam_get_data( pamh, PAM_WINBIND_PWD_LAST_SET, (const void **)&pwdlastset_update); + _pam_get_data( pamh, PAM_WINBIND_PWD_LAST_SET, + &pwdlastset_update); retval = winbind_chauthtok_request(pamh, ctrl, user, pass_old, pass_new, pwdlastset_update); if (retval) { diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index de1edf054d..b1a7947137 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -113,6 +113,116 @@ BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, return True; } +BOOL winbind_lookup_rids(TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + int num_rids, uint32 *rids, + const char **domain_name, + const char ***names, enum SID_NAME_USE **types) +{ + size_t i, buflen; + ssize_t len; + char *ridlist; + char *p; + struct winbindd_request request; + struct winbindd_response response; + NSS_STATUS result; + + if (num_rids == 0) { + return False; + } + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + fstrcpy(request.data.sid, sid_string_static(domain_sid)); + + len = 0; + buflen = 0; + ridlist = NULL; + + for (i=0; i<num_rids; i++) { + sprintf_append(mem_ctx, &ridlist, &len, &buflen, + "%ld\n", rids[i]); + } + + if ((num_rids != 0) && (ridlist == NULL)) { + return False; + } + + request.extra_data.data = ridlist; + request.extra_len = strlen(ridlist)+1; + + result = winbindd_request_response(WINBINDD_LOOKUPRIDS, + &request, &response); + + TALLOC_FREE(ridlist); + + if (result != NSS_STATUS_SUCCESS) { + return False; + } + + *domain_name = talloc_strdup(mem_ctx, response.data.domain_name); + + *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids); + *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids); + + if ((*names == NULL) || (*types == NULL)) { + goto fail; + } + + p = response.extra_data.data; + + for (i=0; i<num_rids; i++) { + char *q; + + if (*p == '\0') { + DEBUG(10, ("Got invalid reply: %s\n", + (char *)response.extra_data.data)); + goto fail; + } + + (*types)[i] = (enum SID_NAME_USE)strtoul(p, &q, 10); + + if (*q != ' ') { + DEBUG(10, ("Got invalid reply: %s\n", + (char *)response.extra_data.data)); + goto fail; + } + + p = q+1; + + q = strchr(p, '\n'); + if (q == NULL) { + DEBUG(10, ("Got invalid reply: %s\n", + (char *)response.extra_data.data)); + goto fail; + } + + *q = '\0'; + + (*names)[i] = talloc_strdup(*names, p); + + p = q+1; + } + + if (*p != '\0') { + DEBUG(10, ("Got invalid reply: %s\n", + (char *)response.extra_data.data)); + goto fail; + } + + SAFE_FREE(response.extra_data.data); + + return True; + + fail: + TALLOC_FREE(*names); + TALLOC_FREE(*types); + return False; +} + /* Call winbindd to convert SID to uid */ BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 27ec27d0be..a393855f02 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -151,6 +151,34 @@ static BOOL wbinfo_get_userinfo(char *user) 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; +} + /* List groups a user is a member of */ static BOOL wbinfo_get_usergroups(char *user) @@ -201,7 +229,7 @@ static BOOL wbinfo_get_usersids(char *user_sid) if (result != NSS_STATUS_SUCCESS) return False; - s = response.extra_data.data; + 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; @@ -608,6 +636,64 @@ static BOOL wbinfo_lookupsid(char *sid) return True; } +/* Lookup a list of RIDs */ + +static BOOL wbinfo_lookuprids(char *domain_sid, char *arg) +{ + size_t i; + DOM_SID sid; + int num_rids; + uint32 *rids; + const char *p; + char ridstr[32]; + const char **names; + enum SID_NAME_USE *types; + const char *domain_name; + TALLOC_CTX *mem_ctx; + + if (!string_to_sid(&sid, domain_sid)) { + d_printf("Could not convert %s to sid\n", domain_sid); + return False; + } + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + d_printf("talloc_new failed\n"); + return False; + } + + num_rids = 0; + rids = NULL; + p = arg; + + while (next_token(&p, ridstr, " ,\n", sizeof(ridstr))) { + uint32 rid = strtoul(ridstr, NULL, 10); + ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids); + } + + if (rids == NULL) { + TALLOC_FREE(mem_ctx); + return False; + } + + if (!winbind_lookup_rids(mem_ctx, &sid, num_rids, rids, + &domain_name, &names, &types)) { + d_printf("winbind_lookup_rids failed\n"); + TALLOC_FREE(mem_ctx); + return False; + } + + d_printf("Domain: %s\n", domain_name); + + for (i=0; i<num_rids; i++) { + d_printf("%8d: %s (%s)\n", rids[i], names[i], + sid_type_lookup(types[i])); + } + + TALLOC_FREE(mem_ctx); + return True; +} + /* Convert string to sid */ static BOOL wbinfo_lookupname(char *name) @@ -1092,7 +1178,8 @@ enum { OPT_ALLOCATE_GID, OPT_SEPARATOR, OPT_LIST_ALL_DOMAINS, - OPT_LIST_OWN_DOMAIN + OPT_LIST_OWN_DOMAIN, + OPT_GROUP_INFO, }; int main(int argc, char **argv) @@ -1117,6 +1204,7 @@ int main(int argc, char **argv) { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" }, { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" }, { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" }, + { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" }, { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" }, { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" }, { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" }, @@ -1132,6 +1220,7 @@ int main(int argc, char **argv) { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" }, { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" }, { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" }, + { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" }, { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" }, { "user-domgroups", 0, POPT_ARG_STRING, &string_arg, OPT_USERDOMGROUPS, "Get user domain groups", "SID" }, @@ -1210,6 +1299,12 @@ int main(int argc, char **argv) goto done; } break; + case 'R': + if (!wbinfo_lookuprids(opt_domain_name, string_arg)) { + d_fprintf(stderr, "Could not lookup RIDs %s\n", string_arg); + goto done; + } + break; case 'n': if (!wbinfo_lookupname(string_arg)) { d_fprintf(stderr, "Could not lookup name %s\n", string_arg); @@ -1298,6 +1393,13 @@ int main(int argc, char **argv) goto done; } break; + case OPT_GROUP_INFO: + if ( !wbinfo_get_groupinfo(string_arg)) { + d_fprintf(stderr, "Could not get info for " + "group %s\n", string_arg); + goto done; + } + break; case 'r': if (!wbinfo_get_usergroups(string_arg)) { d_fprintf(stderr, "Could not get groups for user %s\n", diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 046ea40f59..e5582915b2 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -227,6 +227,7 @@ static struct winbindd_dispatch_table { { WINBINDD_LOOKUPSID, winbindd_lookupsid, "LOOKUPSID" }, { WINBINDD_LOOKUPNAME, winbindd_lookupname, "LOOKUPNAME" }, + { WINBINDD_LOOKUPRIDS, winbindd_lookuprids, "LOOKUPRIDS" }, /* Lookup related functions */ diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 7d5330dccb..a16613258b 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -245,6 +245,15 @@ struct winbindd_methods { char **name, enum SID_NAME_USE *type); + NTSTATUS (*rids_to_names)(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + uint32 *rids, + size_t num_rids, + char **domain_name, + char ***names, + enum SID_NAME_USE **types); + /* lookup user info for a given SID */ NTSTATUS (*query_user)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 250b5f3b8c..07127a6316 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -1119,6 +1119,7 @@ struct winbindd_methods ads_methods = { enum_local_groups, msrpc_name_to_sid, msrpc_sid_to_name, + msrpc_rids_to_names, query_user, lookup_usergroups, msrpc_lookup_useraliases, diff --git a/source3/nsswitch/winbindd_async.c b/source3/nsswitch/winbindd_async.c index 7f282df929..6169b8299e 100644 --- a/source3/nsswitch/winbindd_async.c +++ b/source3/nsswitch/winbindd_async.c @@ -116,7 +116,7 @@ static void idmap_set_mapping_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ) = c; + void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c; if (!success) { DEBUG(5, ("Could not trigger idmap_set_mapping\n")); @@ -149,7 +149,7 @@ void idmap_set_mapping_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, sid_to_string(request.data.dual_idmapset.sid, sid); do_async(mem_ctx, idmap_child(), &request, idmap_set_mapping_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_idmapset(struct winbindd_domain *domain, @@ -188,7 +188,7 @@ void idmap_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc, sid_to_string(request.data.dual_sid2id.sid, sid); request.data.dual_sid2id.alloc = alloc; do_async(mem_ctx, idmap_child(), &request, idmap_sid2uid_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, @@ -211,7 +211,7 @@ enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, result = idmap_sid_to_uid(&sid, &(state->response.data.uid), state->request.data.dual_sid2id.alloc ? - 0 : ID_QUERY_ONLY); + 0 : IDMAP_FLAG_QUERY_ONLY); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -220,7 +220,8 @@ static void idmap_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ, uid_t uid) = c; + void (*cont)(void *priv, BOOL succ, uid_t uid) = + (void (*)(void *, BOOL, uid_t))c; if (!success) { DEBUG(5, ("Could not trigger sid2uid\n")); @@ -251,7 +252,7 @@ void winbindd_uid2name_async(TALLOC_CTX *mem_ctx, uid_t uid, request.cmd = WINBINDD_DUAL_UID2NAME; request.data.uid = uid; do_async(mem_ctx, idmap_child(), &request, uid2name_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain, @@ -277,7 +278,8 @@ static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ, const char *name) = c; + void (*cont)(void *priv, BOOL succ, const char *name) = + (void (*)(void *, BOOL, const char *))c; if (!success) { DEBUG(5, ("Could not trigger uid2name\n")); @@ -308,7 +310,7 @@ static void winbindd_name2uid_async(TALLOC_CTX *mem_ctx, const char *name, request.cmd = WINBINDD_DUAL_NAME2UID; fstrcpy(request.data.username, name); do_async(mem_ctx, idmap_child(), &request, name2uid_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain, @@ -336,7 +338,8 @@ static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ, uid_t uid) = c; + void (*cont)(void *priv, BOOL succ, uid_t uid) = + (void (*)(void *, BOOL, uid_t))c; if (!success) { DEBUG(5, ("Could not trigger name2uid\n")); @@ -371,7 +374,7 @@ void idmap_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc, request.data.dual_sid2id.alloc = alloc; do_async(mem_ctx, idmap_child(), &request, idmap_sid2gid_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, @@ -392,9 +395,9 @@ enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, /* Find gid for this sid and return it, possibly ask the slow remote * idmap */ - result = idmap_sid_to_gid(&sid, &(state->response.data.gid), + result = idmap_sid_to_gid(&sid, &state->response.data.gid, state->request.data.dual_sid2id.alloc ? - 0 : ID_QUERY_ONLY); + 0 : IDMAP_FLAG_QUERY_ONLY); /* If the lookup failed, the perhaps we need to look at the passdb for local groups */ @@ -412,7 +415,8 @@ static void idmap_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ, gid_t gid) = c; + void (*cont)(void *priv, BOOL succ, gid_t gid) = + (void (*)(void *, BOOL, gid_t))c; if (!success) { DEBUG(5, ("Could not trigger sid2gid\n")); @@ -433,7 +437,8 @@ static void gid2name_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ, const char *name) = c; + void (*cont)(void *priv, BOOL succ, const char *name) = + (void (*)(void *, BOOL, const char *))c; if (!success) { DEBUG(5, ("Could not trigger gid2name\n")); @@ -460,7 +465,7 @@ void winbindd_gid2name_async(TALLOC_CTX *mem_ctx, gid_t gid, request.cmd = WINBINDD_DUAL_GID2NAME; request.data.gid = gid; do_async(mem_ctx, idmap_child(), &request, gid2name_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain, @@ -493,7 +498,7 @@ static void winbindd_name2gid_async(TALLOC_CTX *mem_ctx, const char *name, request.cmd = WINBINDD_DUAL_NAME2GID; fstrcpy(request.data.groupname, name); do_async(mem_ctx, idmap_child(), &request, name2gid_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_name2gid(struct winbindd_domain *domain, @@ -521,7 +526,8 @@ static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { - void (*cont)(void *priv, BOOL succ, gid_t gid) = c; + void (*cont)(void *priv, BOOL succ, gid_t gid) = + (void (*)(void *, BOOL, gid_t))c; if (!success) { DEBUG(5, ("Could not trigger name2gid\n")); @@ -544,7 +550,9 @@ static void lookupsid_recv(TALLOC_CTX *mem_ctx, BOOL success, void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const char *dom_name, - const char *name, enum SID_NAME_USE type) = c; + const char *name, enum SID_NAME_USE type) = + (void (*)(void *, BOOL, const char *, const char *, + enum SID_NAME_USE))c; if (!success) { DEBUG(5, ("Could not trigger lookupsid\n")); @@ -559,7 +567,8 @@ static void lookupsid_recv(TALLOC_CTX *mem_ctx, BOOL success, } cont(private_data, True, response->data.name.dom_name, - response->data.name.name, response->data.name.type); + response->data.name.name, + (enum SID_NAME_USE)response->data.name.type); } void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, @@ -585,7 +594,7 @@ void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, fstrcpy(request.data.sid, sid_string_static(sid)); do_async_domain(mem_ctx, domain, &request, lookupsid_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, @@ -628,7 +637,8 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success, void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, const DOM_SID *sid, - enum SID_NAME_USE type) = c; + enum SID_NAME_USE type) = + (void (*)(void *, BOOL, const DOM_SID *, enum SID_NAME_USE))c; DOM_SID sid; if (!success) { @@ -650,7 +660,8 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success, return; } - cont(private_data, True, &sid, response->data.sid.type); + cont(private_data, True, &sid, + (enum SID_NAME_USE)response->data.sid.type); } void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name, @@ -677,7 +688,7 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name, fstrcpy(request.data.name.name, name); do_async_domain(mem_ctx, domain, &request, lookupname_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, @@ -740,8 +751,8 @@ BOOL print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, return True; } -BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, - DOM_SID **sids, size_t *num_sids) +static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, + DOM_SID **sids, size_t *num_sids) { char *p, *q; @@ -768,28 +779,8 @@ BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, return True; } -BOOL print_ridlist(TALLOC_CTX *mem_ctx, uint32 *rids, size_t num_rids, - char **result, ssize_t *len) -{ - size_t i; - size_t buflen = 0; - - *len = 0; - *result = NULL; - for (i=0; i<num_rids; i++) { - sprintf_append(mem_ctx, result, len, &buflen, - "%ld\n", rids[i]); - } - - if ((num_rids != 0) && (*result == NULL)) { - return False; - } - - return True; -} - -BOOL parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr, - uint32 **sids, size_t *num_rids) +static BOOL parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr, + uint32 **rids, size_t *num_rids) { char *p; @@ -806,17 +797,76 @@ BOOL parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr, return False; } p = q+1; - ADD_TO_ARRAY(mem_ctx, uint32, rid, sids, num_rids); + ADD_TO_ARRAY(mem_ctx, uint32, rid, rids, num_rids); } return True; } +enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + uint32 *rids = NULL; + size_t i, buflen, num_rids = 0; + ssize_t len; + DOM_SID domain_sid; + char *domain_name; + char **names; + enum SID_NAME_USE *types; + NTSTATUS status; + char *result; + + DEBUG(10, ("Looking up RIDs for domain %s (%s)\n", + state->request.domain_name, + state->request.data.sid)); + + if (!parse_ridlist(state->mem_ctx, state->request.extra_data.data, + &rids, &num_rids)) { + DEBUG(5, ("Could not parse ridlist\n")); + return WINBINDD_ERROR; + } + + if (!string_to_sid(&domain_sid, state->request.data.sid)) { + DEBUG(5, ("Could not parse domain sid %s\n", + state->request.data.sid)); + return WINBINDD_ERROR; + } + + status = domain->methods->rids_to_names(domain, state->mem_ctx, + &domain_sid, rids, num_rids, + &domain_name, + &names, &types); + + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { + return WINBINDD_ERROR; + } + + len = 0; + buflen = 0; + result = NULL; + + for (i=0; i<num_rids; i++) { + sprintf_append(state->mem_ctx, &result, &len, &buflen, + "%d %s\n", types[i], names[i]); + } + + fstrcpy(state->response.data.domain_name, domain_name); + + if (result != NULL) { + state->response.extra_data.data = SMB_STRDUP(result); + state->response.length += len+1; + } + + return WINBINDD_OK; +} + static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) { void (*cont)(void *priv, BOOL succ, - DOM_SID *aliases, size_t num_aliases) = c; + DOM_SID *aliases, size_t num_aliases) = + (void (*)(void *, BOOL, DOM_SID *, size_t))c; char *aliases_str; DOM_SID *sids = NULL; size_t num_sids = 0; @@ -833,7 +883,7 @@ static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success, return; } - aliases_str = response->extra_data.data; + aliases_str = (char *)response->extra_data.data; if (aliases_str == NULL) { DEBUG(10, ("getsidaliases return 0 SIDs\n")); @@ -881,7 +931,7 @@ void winbindd_getsidaliases_async(struct winbindd_domain *domain, request.extra_data.data = sidstr; do_async_domain(mem_ctx, domain, &request, getsidaliases_recv, - cont, private_data); + (void *)cont, private_data); } enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, @@ -937,12 +987,15 @@ enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, add_sid_to_array(state->mem_ctx, &sid, &sids, &num_sids); } - if (!print_sidlist(NULL, sids, num_sids, - (char **)&state->response.extra_data.data, &len)) { + + if (!print_sidlist(NULL, sids, num_sids, &sidstr, &len)) { DEBUG(0, ("Could not print_sidlist\n")); + state->response.extra_data.data = NULL; return WINBINDD_ERROR; } + state->response.extra_data.data = sidstr; + if (state->response.extra_data.data != NULL) { DEBUG(10, ("aliases_list: %s\n", (char *)state->response.extra_data.data)); @@ -1026,7 +1079,7 @@ static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, return; } - sids_str = response->extra_data.data; + sids_str = (char *)response->extra_data.data; if (sids_str == NULL) { /* This could be normal if we are dealing with a @@ -1070,7 +1123,7 @@ static void gettoken_recvaliases(void *private_data, BOOL success, const DOM_SID *aliases, size_t num_aliases) { - struct gettoken_state *state = private_data; + struct gettoken_state *state = (struct gettoken_state *)private_data; size_t i; if (!success) { @@ -1140,7 +1193,7 @@ void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, /* Query only the local tdb, everything else might possibly block */ - result = idmap_sid_to_uid(sid, &uid, ID_QUERY_ONLY|ID_CACHE_ONLY); + result = idmap_sid_to_uid(sid, &uid, IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { cont(private_data, True, uid); @@ -1302,7 +1355,7 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, /* Query only the local tdb, everything else might possibly block */ - result = idmap_sid_to_gid(sid, &gid, ID_QUERY_ONLY|ID_CACHE_ONLY); + result = idmap_sid_to_gid(sid, &gid, IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { cont(private_data, True, gid); @@ -1437,7 +1490,9 @@ static void query_user_recv(TALLOC_CTX *mem_ctx, BOOL success, { void (*cont)(void *priv, BOOL succ, const char *acct_name, const char *full_name, const char *homedir, - const char *shell, uint32 group_rid) = c; + const char *shell, uint32 group_rid) = + (void (*)(void *, BOOL, const char *, const char *, + const char *, const char *, uint32))c; if (!success) { DEBUG(5, ("Could not trigger query_user\n")); @@ -1467,5 +1522,5 @@ void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, request.cmd = WINBINDD_DUAL_USERINFO; sid_to_string(request.data.sid, sid); do_async_domain(mem_ctx, domain, &request, query_user_recv, - cont, private_data); + (void *)cont, private_data); } diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index b267a3f770..95a66420c5 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -66,7 +66,7 @@ void winbindd_check_cache_size(time_t t) return; } - if (fstat(wcache->tdb->fd, &st) == -1) { + if (fstat(tdb_fd(wcache->tdb), &st) == -1) { DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) )); return; } @@ -259,7 +259,7 @@ static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx) smb_panic("centry_string"); } - ret = TALLOC(mem_ctx, len+1); + ret = TALLOC_ARRAY(mem_ctx, char, len+1); if (!ret) { smb_panic("centry_string out of memory\n"); } @@ -567,7 +567,8 @@ static void centry_expand(struct cache_entry *centry, uint32 len) if (centry->len - centry->ofs >= len) return; centry->len *= 2; - centry->data = SMB_REALLOC(centry->data, centry->len); + centry->data = SMB_REALLOC_ARRAY(centry->data, unsigned char, + centry->len); if (!centry->data) { DEBUG(0,("out of memory: needed %d bytes in centry_expand\n", centry->len)); smb_panic("out of memory in centry_expand"); @@ -1316,6 +1317,128 @@ do_query: return status; } +static NTSTATUS rids_to_names(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + uint32 *rids, + size_t num_rids, + char **domain_name, + char ***names, + enum SID_NAME_USE **types) +{ + struct winbind_cache *cache = get_cache(domain); + size_t i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + BOOL have_mapped; + BOOL have_unmapped; + + *domain_name = NULL; + *names = NULL; + *types = NULL; + + if (!cache->tdb) { + goto do_query; + } + + if (num_rids == 0) { + return NT_STATUS_OK; + } + + *names = TALLOC_ARRAY(mem_ctx, char *, num_rids); + *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids); + + if ((*names == NULL) || (*types == NULL)) { + result = NT_STATUS_NO_MEMORY; + goto error; + } + + have_mapped = have_unmapped = False; + + for (i=0; i<num_rids; i++) { + DOM_SID sid; + struct cache_entry *centry; + + if (!sid_compose(&sid, domain_sid, rids[i])) { + result = NT_STATUS_INTERNAL_ERROR; + goto error; + } + + centry = wcache_fetch(cache, domain, "SN/%s", + sid_string_static(&sid)); + if (!centry) { + goto do_query; + } + + (*types)[i] = SID_NAME_UNKNOWN; + (*names)[i] = talloc_strdup(*names, ""); + + if (NT_STATUS_IS_OK(centry->status)) { + char *dom; + have_mapped = True; + (*types)[i] = (enum SID_NAME_USE)centry_uint32(centry); + dom = centry_string(centry, mem_ctx); + if (*domain_name == NULL) { + *domain_name = dom; + } else { + talloc_free(dom); + } + (*names)[i] = centry_string(centry, *names); + } else { + have_unmapped = True; + } + + centry_free(centry); + } + + if (!have_mapped) { + return NT_STATUS_NONE_MAPPED; + } + if (!have_unmapped) { + return NT_STATUS_OK; + } + return STATUS_SOME_UNMAPPED; + + do_query: + + TALLOC_FREE(*names); + TALLOC_FREE(*types); + + result = domain->backend->rids_to_names(domain, mem_ctx, domain_sid, + rids, num_rids, domain_name, + names, types); + + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { + return result; + } + + refresh_sequence_number(domain, False); + + for (i=0; i<num_rids; i++) { + DOM_SID sid; + NTSTATUS status; + + if (!sid_compose(&sid, domain_sid, rids[i])) { + result = NT_STATUS_INTERNAL_ERROR; + goto error; + } + + status = (*types)[i] == SID_NAME_UNKNOWN ? + NT_STATUS_NONE_MAPPED : NT_STATUS_OK; + + wcache_save_sid_to_name(domain, status, &sid, *domain_name, + (*names)[i], (*types)[i]); + } + + return result; + + error: + + TALLOC_FREE(*names); + TALLOC_FREE(*types); + return result; +} + /* Lookup user information from a rid */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -1914,7 +2037,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) fstr_sprintf(key_str, "DR/%d", pid); if (tdb_store(wcache->tdb, string_tdb_data(key_str), - make_tdb_data((void *)response, sizeof(*response)), + make_tdb_data((const char *)response, sizeof(*response)), TDB_REPLACE) == -1) return; @@ -1928,7 +2051,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) fstr_sprintf(key_str, "DE/%d", pid); if (tdb_store(wcache->tdb, string_tdb_data(key_str), - make_tdb_data(response->extra_data.data, + make_tdb_data((const char *)response->extra_data.data, response->length - sizeof(*response)), TDB_REPLACE) == 0) return; @@ -2313,7 +2436,7 @@ BOOL set_global_winbindd_state_offline(void) return True; } - wcache->tdb->ecode = 0; +/* wcache->tdb->ecode = 0; */ data = tdb_fetch_bystring( wcache->tdb, "WINBINDD_OFFLINE" ); @@ -2368,6 +2491,7 @@ struct winbindd_methods cache_methods = { enum_local_groups, name_to_sid, sid_to_name, + rids_to_names, query_user, lookup_usergroups, lookup_useraliases, diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index c1276bd961..2b8a8898ac 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -214,7 +214,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, goto done; } - if ((*cli = cli_initialise(NULL)) == NULL) { + if ((*cli = cli_initialise()) == NULL) { DEBUG(1, ("Could not cli_initialize\n")); result = NT_STATUS_NO_MEMORY; goto done; diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c index 0cc35277b0..5908c78d9a 100644 --- a/source3/nsswitch/winbindd_dual.c +++ b/source3/nsswitch/winbindd_dual.c @@ -345,6 +345,7 @@ static struct winbindd_child_dispatch_table child_dispatch_table[] = { { WINBINDD_LOOKUPSID, winbindd_dual_lookupsid, "LOOKUPSID" }, { WINBINDD_LOOKUPNAME, winbindd_dual_lookupname, "LOOKUPNAME" }, + { WINBINDD_LOOKUPRIDS, winbindd_dual_lookuprids, "LOOKUPRIDS" }, { WINBINDD_LIST_TRUSTDOM, winbindd_dual_list_trusted_domains, "LIST_TRUSTDOM" }, { WINBINDD_INIT_CONNECTION, winbindd_dual_init_connection, "INIT_CONNECTION" }, { WINBINDD_GETDCNAME, winbindd_dual_getdcname, "GETDCNAME" }, diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 2afefcc12c..6167a10c46 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -34,7 +34,7 @@ /* Update this when you change the interface. */ -#define WINBIND_INTERFACE_VERSION 14 +#define WINBIND_INTERFACE_VERSION 15 /* Socket commands */ @@ -76,6 +76,7 @@ enum winbindd_cmd { WINBINDD_LOOKUPSID, WINBINDD_LOOKUPNAME, + WINBINDD_LOOKUPRIDS, /* Lookup functions */ diff --git a/source3/nsswitch/winbindd_passdb.c b/source3/nsswitch/winbindd_passdb.c index b949ea0808..d73917ef83 100644 --- a/source3/nsswitch/winbindd_passdb.c +++ b/source3/nsswitch/winbindd_passdb.c @@ -286,6 +286,18 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, return NT_STATUS_OK; } +static NTSTATUS rids_to_names(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + uint32 *rids, + size_t num_rids, + char **domain_name, + char ***names, + enum SID_NAME_USE **types) +{ + return NT_STATUS_UNSUCCESSFUL; +} + /* Lookup user information from a rid or username. */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -353,15 +365,21 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, const DOM_SID **sids; struct lsa_dom_info *lsa_domains; struct lsa_name_info *lsa_names; + TALLOC_CTX *tmp_ctx; if (!sid_check_is_in_our_domain(group_sid)) { /* There's no groups, only aliases in BUILTIN */ return NT_STATUS_NO_SUCH_GROUP; } - result = pdb_enum_group_members(mem_ctx, group_sid, &rids, + if (!(tmp_ctx = talloc_init("lookup_groupmem"))) { + return NT_STATUS_NO_MEMORY; + } + + result = pdb_enum_group_members(tmp_ctx, group_sid, &rids, &num_members); if (!NT_STATUS_IS_OK(result)) { + TALLOC_FREE(tmp_ctx); return result; } @@ -370,29 +388,39 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, *sid_mem = NULL; *names = NULL; *name_types = NULL; + TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } *sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members); *names = TALLOC_ARRAY(mem_ctx, char *, num_members); *name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members); - sids = TALLOC_ARRAY(mem_ctx, const DOM_SID *, num_members); + sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members); if (((*sid_mem) == NULL) || ((*names) == NULL) || ((*name_types) == NULL) || (sids == NULL)) { + TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; } + /* + * Prepare an array of sid pointers for the lookup_sids calling + * convention. + */ + for (i=0; i<num_members; i++) { DOM_SID *sid = &((*sid_mem)[i]); - sid_copy(sid, &domain->sid); - sid_append_rid(sid, rids[i]); + if (!sid_compose(sid, &domain->sid, rids[i])) { + TALLOC_FREE(tmp_ctx); + return NT_STATUS_INTERNAL_ERROR; + } sids[i] = sid; } - result = lookup_sids(mem_ctx, num_members, sids, 1, + result = lookup_sids(tmp_ctx, num_members, sids, 1, &lsa_domains, &lsa_names); if (!NT_STATUS_IS_OK(result)) { + TALLOC_FREE(tmp_ctx); return result; } @@ -403,8 +431,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, sid_type_lookup(lsa_names[i].type))); continue; } - (*names)[i] = talloc_steal((*names), - lsa_names[i].name); + if (!((*names)[i] = talloc_strdup((*names), + lsa_names[i].name))) { + TALLOC_FREE(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + (*name_types)[i] = lsa_names[i].type; num_mapped += 1; @@ -412,6 +444,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, *num_names = num_mapped; + TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } @@ -497,15 +530,21 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, NTSTATUS nt_status; struct trustdom_info **domains; int i; + TALLOC_CTX *tmp_ctx; *num_domains = 0; *names = NULL; *alt_names = NULL; *dom_sids = NULL; - nt_status = secrets_trusted_domains(mem_ctx, num_domains, + if (!(tmp_ctx = talloc_init("trusted_domains"))) { + return NT_STATUS_NO_MEMORY; + } + + nt_status = secrets_trusted_domains(tmp_ctx, num_domains, &domains); if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE(tmp_ctx); return nt_status; } @@ -514,15 +553,21 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains); if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) { + TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; } for (i=0; i<*num_domains; i++) { (*alt_names)[i] = NULL; - (*names)[i] = talloc_steal((*names), domains[i]->name); + if (!((*names)[i] = talloc_strdup((*names), + domains[i]->name))) { + TALLOC_FREE(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } sid_copy(&(*dom_sids)[i], &domains[i]->sid); } + TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } @@ -534,6 +579,7 @@ struct winbindd_methods passdb_methods = { enum_local_groups, name_to_sid, sid_to_name, + rids_to_names, query_user, lookup_usergroups, lookup_useraliases, diff --git a/source3/nsswitch/winbindd_reconnect.c b/source3/nsswitch/winbindd_reconnect.c index 7bc8be1213..8c5d59f9af 100644 --- a/source3/nsswitch/winbindd_reconnect.c +++ b/source3/nsswitch/winbindd_reconnect.c @@ -125,6 +125,30 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, return result; } +static NTSTATUS rids_to_names(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + uint32 *rids, + size_t num_rids, + char **domain_name, + char ***names, + enum SID_NAME_USE **types) +{ + NTSTATUS result; + + result = msrpc_methods.rids_to_names(domain, mem_ctx, sid, + rids, num_rids, + domain_name, names, types); + if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { + result = msrpc_methods.rids_to_names(domain, mem_ctx, sid, + rids, num_rids, + domain_name, names, + types); + } + + return result; +} + /* Lookup user information from a rid or username. */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -280,6 +304,7 @@ struct winbindd_methods reconnect_methods = { enum_local_groups, name_to_sid, sid_to_name, + rids_to_names, query_user, lookup_usergroups, lookup_useraliases, diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 27feea2f67..d8797ee2bc 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -318,6 +318,58 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, return NT_STATUS_OK; } +NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + uint32 *rids, + size_t num_rids, + char **domain_name, + char ***names, + enum SID_NAME_USE **types) +{ + char **domains; + NTSTATUS result; + struct rpc_pipe_client *cli; + POLICY_HND lsa_policy; + DOM_SID *sids; + size_t i; + + DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name )); + + sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids); + if (sids == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<num_rids; i++) { + if (!sid_compose(&sids[i], sid, rids[i])) { + return NT_STATUS_INTERNAL_ERROR; + } + } + + result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + if (!NT_STATUS_IS_OK(result)) { + return result; + } + + result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy, + num_rids, sids, &domains, + names, types); + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { + return result; + } + + for (i=0; i<num_rids; i++) { + if ((*types)[i] != SID_NAME_UNKNOWN) { + *domain_name = domains[i]; + break; + } + } + + return result; +} + /* Lookup user information from a rid or username. */ static NTSTATUS query_user(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -772,7 +824,6 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) NTSTATUS result; POLICY_HND dom_pol; BOOL got_seq_num = False; - int retry; struct rpc_pipe_client *cli; DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name)); @@ -782,8 +833,6 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) if (!(mem_ctx = talloc_init("sequence_number[rpc]"))) return NT_STATUS_NO_MEMORY; - retry = 0; - #ifdef HAVE_LDAP if ( domain->native_mode ) { @@ -985,6 +1034,7 @@ struct winbindd_methods msrpc_methods = { enum_local_groups, msrpc_name_to_sid, msrpc_sid_to_name, + msrpc_rids_to_names, query_user, lookup_usergroups, msrpc_lookup_useraliases, diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index d489e267cb..4a9e17e4c7 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -124,6 +124,34 @@ static void lookupname_recv(void *private_data, BOOL success, return; } +void winbindd_lookuprids(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + DOM_SID domain_sid; + + /* Ensure null termination */ + state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; + + DEBUG(10, ("lookup_rids: %s\n", state->request.data.sid)); + + if (!string_to_sid(&domain_sid, state->request.data.sid)) { + DEBUG(5, ("Could not convert %s to SID\n", + state->request.data.sid)); + request_error(state); + return; + } + + domain = find_lookup_domain_from_sid(&domain_sid); + if (domain == NULL) { + DEBUG(10, ("Could not find domain for name %s\n", + state->request.domain_name)); + request_error(state); + return; + } + + sendto_domain(state, domain); +} + static struct winbindd_child static_idmap_child; void init_idmap_child(void) @@ -167,8 +195,8 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state) /* Query only the local tdb, everything else might possibly block */ - result = idmap_sid_to_uid(&sid, &(state->response.data.uid), - ID_QUERY_ONLY|ID_CACHE_ONLY); + result = idmap_sid_to_uid(&sid, &state->response.data.uid, + IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { request_ok(state); @@ -225,8 +253,8 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state) /* Query only the local tdb, everything else might possibly block */ - result = idmap_sid_to_gid(&sid, &(state->response.data.gid), - ID_QUERY_ONLY|ID_CACHE_ONLY); + result = idmap_sid_to_gid(&sid, &state->response.data.gid, + IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY); if (NT_STATUS_IS_OK(result)) { request_ok(state); @@ -285,7 +313,7 @@ void winbindd_uid_to_sid(struct winbindd_cli_state *state) } status = idmap_uid_to_sid(&sid, state->request.data.uid, - ID_QUERY_ONLY | ID_CACHE_ONLY); + IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY); if (NT_STATUS_IS_OK(status)) { sid_to_string(state->response.data.sid.sid, &sid); @@ -412,7 +440,7 @@ void winbindd_gid_to_sid(struct winbindd_cli_state *state) } status = idmap_gid_to_sid(&sid, state->request.data.gid, - ID_QUERY_ONLY | ID_CACHE_ONLY); + IDMAP_FLAG_QUERY_ONLY|IDMAP_FLAG_CACHE_ONLY); if (NT_STATUS_IS_OK(status)) { sid_to_string(state->response.data.sid.sid, &sid); diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index a73b5c394c..8a0ebbafa5 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -28,8 +28,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -extern userdom_struct current_user_info; - static BOOL fillup_pw_field(const char *lp_template, const char *username, const char *domname, @@ -53,15 +51,16 @@ static BOOL fillup_pw_field(const char *lp_template, shell. */ /* The substitution of %U and %D in the 'template homedir' is done - by alloc_sub_specified() below. */ + by talloc_sub_specified() below. */ - templ = alloc_sub_specified(lp_template, username, domname, uid, gid); + templ = talloc_sub_specified(NULL, lp_template, username, domname, + uid, gid); if (!templ) return False; safe_strcpy(out, templ, sizeof(fstring) - 1); - SAFE_FREE(templ); + TALLOC_FREE(templ); return True; @@ -109,11 +108,6 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, defaults are /tmp for the home directory and /bin/false for shell. */ - /* The substitution of %U and %D in the 'template homedir' is done - by alloc_sub_specified() below. */ - - fstrcpy(current_user_info.domain, dom_name); - if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir)) return False; @@ -293,8 +287,6 @@ static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid) safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1); - fstrcpy(current_user_info.domain, s->domain->name); - if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name, pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) { DEBUG(5, ("Could not compose homedir\n")); @@ -407,7 +399,7 @@ void winbindd_getpwuid(struct winbindd_cli_state *state) (unsigned long)state->request.data.uid)); status = idmap_uid_to_sid(&user_sid, state->request.data.uid, - ID_QUERY_ONLY | ID_CACHE_ONLY); + IDMAP_FLAG_QUERY_ONLY | IDMAP_FLAG_CACHE_ONLY); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("Could not find SID for uid %lu\n", diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 67b94817ad..25ba20bb9f 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -1096,7 +1096,7 @@ static BOOL idmap_convert(const char *idmap_name) return False; } - bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False; + bigendianheader = (tdb_get_flags(idmap_tdb) & TDB_BIGENDIAN) ? True : False; vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION"); |