diff options
| -rw-r--r-- | source3/nsswitch/winbindd.c | 10 | ||||
| -rw-r--r-- | source3/nsswitch/winbindd_cm.c | 226 | ||||
| -rw-r--r-- | source3/nsswitch/winbindd_proto.h | 11 | ||||
| -rw-r--r-- | source3/nsswitch/winbindd_user.c | 149 | ||||
| -rw-r--r-- | source3/nsswitch/winbindd_util.c | 136 | 
5 files changed, 353 insertions, 179 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 9bf4935eff..21dda58aae 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -230,12 +230,12 @@ static struct dispatch_table dispatch_table[] = {  	{ WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user },  	{ WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid }, -#if 0 -  	{ WINBINDD_SETPWENT, winbindd_setpwent },  	{ WINBINDD_ENDPWENT, winbindd_endpwent },  	{ WINBINDD_GETPWENT, winbindd_getpwent }, +#if 0 +  	{ WINBINDD_GETGROUPS, winbindd_getgroups },  	/* Group functions */ @@ -699,6 +699,12 @@ int main(int argc, char **argv)  	secrets_init(); +        /* Get list of domains we look up requests for.  This includes the +           domain which we are a member of as well as any trusted +           domains. */  + +        get_domain_info(); +  	ZERO_STRUCT(server_state);  	/* Winbind daemon initialisation */ diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index ec1db826dd..df9c553b0b 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -33,15 +33,13 @@         - manage re-entrancy for when winbindd becomes able to handle           multiple outstanding rpc requests -   We can also throw away the CLI_POLICY_HND stuff as all this information -   will be stored within this module. -       Why not have connection management as part of the rpc layer like tng?     Good question.  This code may morph into libsmb/rpc_cache.c or something     like that but at the moment it's simply staying as part of winbind.  I     think the TNG architecture of forcing every user of the rpc layer to use     the connection caching system is a bad idea.  It should be an optional -   method of using the routines. +   method of using the routines.  We actually cache policy handles - tng +   caches connections to pipes.     The TNG design is quite good but I disagree with some aspects of the     implementation. -tpot @@ -55,7 +53,13 @@         moved down into another function.       - There needs to be a utility function in libsmb/namequery.c that does -       get_any_dc_name()  +       cm_get_dc_name()  + +     - When closing down sam handles we need to close down user, group and +       domain handles. + +     - Take care when destroying cli_structs as they can be shared between +       various sam handles.   */ @@ -63,13 +67,25 @@  /* We store lists of connections here */ +enum sam_pipe_type { +        SAM_PIPE_BASIC,         /* A basic handle */ +        SAM_PIPE_DOM,           /* A domain handle */ +        SAM_PIPE_USER,          /* A handle on a user */ +        SAM_PIPE_GROUP          /* A handle on a group */ +}; +  struct winbindd_cm_conn {          struct winbindd_cm_conn *prev, *next;          fstring domain;          fstring controller;          fstring pipe_name; -        struct cli_state cli; +        struct cli_state *cli;          POLICY_HND pol; + +        /* Specific pipe stuff - move into a union? */ + +        enum sam_pipe_type sam_pipe_type; /* Domain, user, group etc  */ +        uint32 user_rid;  };  /* Global list of connections.  Initially a DLIST but can become a hash @@ -122,19 +138,17 @@ static BOOL cm_open_connection(char *domain, char *pipe_name,          BOOL result = False;          struct ntuser_creds creds; -        ZERO_STRUCT(new_conn->cli); -          fstrcpy(new_conn->domain, domain);          fstrcpy(new_conn->pipe_name, pipe_name);          /* Look for a domain controller for this domain */ -        if (!cm_get_dc_name(lp_workgroup(), new_conn->controller)) +        if (!cm_get_dc_name(domain, new_conn->controller))                  goto done;          /* Initialise SMB connection */ -        if (!cli_initialise(&new_conn->cli)) +        if (!(new_conn->cli = cli_initialise(NULL)))                  goto done;  	if (!resolve_srv_name(new_conn->controller, dest_host, &dest_ip)) @@ -147,21 +161,21 @@ static BOOL cm_open_connection(char *domain, char *pipe_name,  	ZERO_STRUCT(creds);  	creds.pwd.null_pwd = 1; -	cli_init_creds(&new_conn->cli, &creds); +	cli_init_creds(new_conn->cli, &creds); -	if (!cli_establish_connection(&new_conn->cli, new_conn->controller,  +	if (!cli_establish_connection(new_conn->cli, new_conn->controller,                                         &dest_ip, &calling, &called, "IPC$",                                         "IPC", False, True))  		goto done; -	if (!cli_nt_session_open (&new_conn->cli, pipe_name)) +	if (!cli_nt_session_open (new_conn->cli, pipe_name))  		goto done;          result = True;   done: -        if (!result) -                cli_shutdown(&new_conn->cli); +        if (!result && new_conn->cli) +                cli_shutdown(new_conn->cli);          return result;  } @@ -189,13 +203,15 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain)                malloc(sizeof(struct winbindd_cm_conn))))                  return NULL; +        ZERO_STRUCTP(conn); +          if (!cm_open_connection(domain, PIPE_LSARPC, conn)) {                  DEBUG(3, ("Could not connect to a dc for domain %s\n",                            domain));                  return NULL;          } -        result = cli_lsa_open_policy(&conn->cli, conn->cli.mem_ctx, False,  +        result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,                                        des_access, &conn->pol);          if (!NT_STATUS_IS_OK(result)) @@ -207,7 +223,7 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain)   ok:          hnd.pol = conn->pol; -        hnd.cli = &conn->cli; +        hnd.cli = conn->cli;          return &hnd;  } @@ -216,24 +232,184 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain)  CLI_POLICY_HND *cm_get_sam_handle(char *domain)  {  -        DEBUG(0, ("get_sam_handle(): not implemented\n")); -        return NULL; +        struct winbindd_cm_conn *conn; +        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; +        NTSTATUS result; +        static CLI_POLICY_HND hnd; + +        /* Look for existing connections */ + +        for (conn = cm_conns; conn; conn = conn->next) { +                if (strequal(conn->domain, domain) && +                    strequal(conn->pipe_name, PIPE_SAMR) && +                    conn->sam_pipe_type == SAM_PIPE_BASIC) +                        goto ok; +        } + +        /* Create a new one */ + +        if (!(conn = (struct winbindd_cm_conn *) +              malloc(sizeof(struct winbindd_cm_conn)))) +                return NULL; + +        ZERO_STRUCTP(conn); + +        if (!cm_open_connection(domain, PIPE_SAMR, conn)) { +                DEBUG(3, ("Could not connect to a dc for domain %s\n", +                          domain)); +                return NULL; +        } + +        result = cli_samr_connect(conn->cli, conn->cli->mem_ctx, des_access,  +                                  &conn->pol); + +        if (!NT_STATUS_IS_OK(result)) +                return NULL; + +        /* Add to list */ + +        DLIST_ADD(cm_conns, conn); + + ok: +        hnd.pol = conn->pol; +        hnd.cli = conn->cli; + +        return &hnd;          }  /* Return a SAM domain policy handle on a domain */ -CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain) +CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid)  { -        DEBUG(0, ("get_sam_dom_handle(): not implemented\n")); -        return NULL; +        struct winbindd_cm_conn *conn, *basic_conn = NULL; +        static CLI_POLICY_HND hnd; +        NTSTATUS result; +        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + +        /* Look for existing connections */ + +        for (conn = cm_conns; conn; conn = conn->next) { +                if (strequal(conn->domain, domain) && +                    strequal(conn->pipe_name, PIPE_SAMR) && +                    conn->sam_pipe_type == SAM_PIPE_DOM) +                        goto ok; +        } + +        /* Create a basic handle to open a domain handle from */ + +        if (!cm_get_sam_handle(domain)) +                return False; + +        for (conn = cm_conns; conn; conn = conn->next) { +                if (strequal(conn->domain, domain) && +                    strequal(conn->pipe_name, PIPE_SAMR) && +                    conn->sam_pipe_type == SAM_PIPE_BASIC) +                        basic_conn = conn; +        } +         +        if (!basic_conn) { +                DEBUG(0, ("No basic sam handle was created!\n")); +                return NULL; + +                } +        if (!(conn = (struct winbindd_cm_conn *) +              malloc(sizeof(struct winbindd_cm_conn)))) +                return NULL; +         +        ZERO_STRUCTP(conn); + +        fstrcpy(conn->domain, basic_conn->domain); +        fstrcpy(conn->controller, basic_conn->controller); +        fstrcpy(conn->pipe_name, basic_conn->pipe_name); + +        conn->sam_pipe_type = SAM_PIPE_DOM; +        conn->cli = basic_conn->cli; + +        result = cli_samr_open_domain(conn->cli, conn->cli->mem_ctx, +                                      &basic_conn->pol, des_access,  +                                      domain_sid, &conn->pol); + +        if (!NT_STATUS_IS_OK(result)) +                return NULL; + +        /* Add to list */ + +        DLIST_ADD(cm_conns, conn); + + ok: +        hnd.pol = conn->pol; +        hnd.cli = conn->cli; + +        return &hnd;  }  /* Return a SAM policy handle on a domain user */ -CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, char *user) +CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid, +                                       uint32 user_rid)  { -        DEBUG(0, ("get_sam_user_handle(): not implemented\n")); -        return NULL; +        struct winbindd_cm_conn *conn, *basic_conn = NULL; +        static CLI_POLICY_HND hnd; +        NTSTATUS result; +        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + +        /* Look for existing connections */ + +        for (conn = cm_conns; conn; conn = conn->next) { +                if (strequal(conn->domain, domain) && +                    strequal(conn->pipe_name, PIPE_SAMR) && +                    conn->sam_pipe_type == SAM_PIPE_USER && +                    conn->user_rid == user_rid) +                        goto ok; +        } + +        /* Create a domain handle to open a user handle from */ + +        if (!cm_get_sam_dom_handle(domain, domain_sid)) +                return NULL; + +        for (conn = cm_conns; conn; conn = conn->next) { +                if (strequal(conn->domain, domain) && +                    strequal(conn->pipe_name, PIPE_SAMR) && +                    conn->sam_pipe_type == SAM_PIPE_DOM) +                        basic_conn = conn; +        } +         +        if (!basic_conn) { +                DEBUG(0, ("No domain sam handle was created!\n")); +                return NULL; +        } + +        if (!(conn = (struct winbindd_cm_conn *) +              malloc(sizeof(struct winbindd_cm_conn)))) +                return NULL; +         +        ZERO_STRUCTP(conn); + +        fstrcpy(conn->domain, basic_conn->domain); +        fstrcpy(conn->controller, basic_conn->controller); +        fstrcpy(conn->pipe_name, basic_conn->pipe_name); +         +        conn->sam_pipe_type = SAM_PIPE_USER; +        conn->cli = basic_conn->cli; +        conn->user_rid = user_rid; + +        result = cli_samr_open_user(conn->cli, conn->cli->mem_ctx, +                                    &basic_conn->pol, des_access, user_rid, +                                    &conn->pol); + +        if (!NT_STATUS_IS_OK(result)) +                return NULL; + +        /* Add to list */ + +        DLIST_ADD(cm_conns, conn); + + ok: +        hnd.pol = conn->pol; +        hnd.cli = conn->cli; + +        return &hnd;  }  /* Return a SAM policy handle on a domain group */ diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index 7b4e36576d..3c44b63234 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -50,8 +50,9 @@ void winbindd_cache_dump_status(void);  BOOL cm_get_dc_name(char *domain, fstring srv_name);  CLI_POLICY_HND *cm_get_lsa_handle(char *domain);  CLI_POLICY_HND *cm_get_sam_handle(char *domain); -CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain); -CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, char *user); +CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid); +CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid, +                                       uint32 user_rid);  CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, char *group);  /* The following definitions come from nsswitch/winbindd_group.c  */ @@ -115,17 +116,17 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state);  /* The following definitions come from nsswitch/winbindd_util.c  */ +BOOL get_domain_info(void);  BOOL domain_handles_open(struct winbindd_domain *domain);  void winbindd_kill_all_connections(void);  void establish_connections(BOOL force_reestablish) ;  BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain); -BOOL get_domain_info(struct winbindd_domain *domain);  BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,                                   enum SID_NAME_USE *type);  BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,                                   enum SID_NAME_USE *type); -BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, -                              uint32 user_rid, SAM_USERINFO_CTR **user_info); +BOOL winbindd_lookup_userinfo(char *domain, uint32 user_rid,  +                              SAM_USERINFO_CTR **user_info);  BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,  				uint32 user_rid, uint32 *num_groups,  				DOM_GID **user_groups); diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index bb5b1e354e..25ab38dd8c 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -145,9 +145,7 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state  	/* The following costs 3 packets */ -#if 0 - -	if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) { +	if (!winbindd_lookup_userinfo(name_domain, user_rid, &user_info)) {  		DEBUG(1, ("pwnam_from_user(): error getting user info for "  			  "user '%s'\n", name_user));  		return WINBINDD_ERROR; @@ -157,11 +155,6 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state  	unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,  			 sizeof(gecos_name) - 1); -#endif - -        group_rid = DOMAIN_GROUP_RID_GUESTS; -        fstrcpy(gecos_name, "foo"); -	  	/* Now take all this information and fill in a passwd structure */  	if (!winbindd_fill_pwent(name_domain, state->request.data.username,  @@ -236,9 +229,7 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state  	/* Get some user info */ -#if 0 - -	if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) { +	if (!winbindd_lookup_userinfo(domain->name, user_rid, &user_info)) {  		DEBUG(1, ("pwnam_from_uid(): error getting user info for "  			  "user '%s'\n", user_name));  		return WINBINDD_ERROR; @@ -247,10 +238,6 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state  	group_rid = user_info->info.id21->group_rid;  	unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,  			 sizeof(gecos_name) - 1); -#endif - -        group_rid = DOMAIN_GROUP_RID_GUESTS; -        fstrcpy(gecos_name, "foo");  	/* Resolve gid number */ @@ -272,8 +259,6 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state  	return WINBINDD_OK;  } -#if 0 -  /*   * set/get/endpwent functions   */ @@ -282,68 +267,61 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state  enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)  { -    struct winbindd_domain *tmp; - -    DEBUG(3, ("[%5d]: setpwent\n", state->pid)); - -    if (state == NULL) return WINBINDD_ERROR; -     -    /* Check user has enabled this */ - -    if (!lp_winbind_enum_users()) { -	    return WINBINDD_ERROR; -    } - -    /* Free old static data if it exists */ - -    if (state->getpwent_state != NULL) { -        free_getent_state(state->getpwent_state); -        state->getpwent_state = NULL; -    } - -    /* Create sam pipes for each domain we know about */ - -    for(tmp = domain_list; tmp != NULL; tmp = tmp->next) { -        struct getent_state *domain_state; - -        /* Skip domains other than WINBINDD_DOMAIN environment variable */ - -        if ((strcmp(state->request.domain, "") != 0) && -	    !check_domain_env(state->request.domain, tmp->name)) { -                continue; +        struct winbindd_domain *tmp; +         +        DEBUG(3, ("[%5d]: setpwent\n", state->pid)); +         +        /* Check user has enabled this */ +         +        if (!lp_winbind_enum_users()) +                return WINBINDD_ERROR; + +        /* Free old static data if it exists */ +         +        if (state->getpwent_state != NULL) { +                free_getent_state(state->getpwent_state); +                state->getpwent_state = NULL;          } - -        /* Create a state record for this domain */ - -        if ((domain_state = (struct getent_state *) -             malloc(sizeof(struct getent_state))) == NULL) { - -            return WINBINDD_ERROR; +         +        /* Create sam pipes for each domain we know about */ +         +        for(tmp = domain_list; tmp != NULL; tmp = tmp->next) { +                struct getent_state *domain_state; +                 +                /* Skip domains other than WINBINDD_DOMAIN environment +                   variable */ +                 +                if ((strcmp(state->request.domain, "") != 0) && +                    !check_domain_env(state->request.domain, tmp->name)) +                        continue; + +                /* Create a state record for this domain */ +                 +                if ((domain_state = (struct getent_state *) +                     malloc(sizeof(struct getent_state))) == NULL) +                        return WINBINDD_ERROR; +                 +                ZERO_STRUCTP(domain_state); +                domain_state->domain = tmp; + +                /* Add to list of open domains */ +                 +                DLIST_ADD(state->getpwent_state, domain_state);          } - -        ZERO_STRUCTP(domain_state); -        domain_state->domain = tmp; - -        /* Add to list of open domains */ - -        DLIST_ADD(state->getpwent_state, domain_state) -    } - -    return WINBINDD_OK; +         +        return WINBINDD_OK;  }  /* Close file pointer to ntdom passwd database */  enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)  { -    DEBUG(3, ("[%5d]: endpwent\n", state->pid)); - -    if (state == NULL) return WINBINDD_ERROR; +        DEBUG(3, ("[%5d]: endpwent\n", state->pid)); -    free_getent_state(state->getpwent_state);     -    state->getpwent_state = NULL; - -    return WINBINDD_OK; +        free_getent_state(state->getpwent_state);     +        state->getpwent_state = NULL; +         +        return WINBINDD_OK;  }  /* Get partial list of domain users for a domain.  We fill in the sam_entries, @@ -362,9 +340,8 @@ static BOOL get_sam_user_entries(struct getent_state *ent)  	struct getpwent_user *name_list = NULL;  	uint32 group_rid; -	if (ent->got_all_sam_entries) { +	if (ent->got_all_sam_entries)  		return False; -	}  	ZERO_STRUCT(info1);  	ZERO_STRUCT(ctr); @@ -390,10 +367,6 @@ static BOOL get_sam_user_entries(struct getent_state *ent)  	group_rid = DOMAIN_GROUP_RID_USERS; -	if (!domain_handles_open(ent->domain)) { -		return WINBINDD_ERROR; -	} -  	/* Free any existing user info */  	SAFE_FREE(ent->sam_entries); @@ -486,22 +459,18 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)  	DEBUG(3, ("[%5d]: getpwent\n", state->pid)); -	if (state == NULL) return WINBINDD_ERROR; -  	/* Check user has enabled this */ -	if (!lp_winbind_enum_users()) { +	if (!lp_winbind_enum_users())  		return WINBINDD_ERROR; -	}  	/* Allocate space for returning a chunk of users */  	num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries);  	if ((state->response.extra_data =  -	     malloc(num_users * sizeof(struct winbindd_pw))) == NULL) { +	     malloc(num_users * sizeof(struct winbindd_pw))) == NULL)  		return WINBINDD_ERROR; -	}  	memset(state->response.extra_data, 0, num_users *   	       sizeof(struct winbindd_pw)); @@ -509,9 +478,8 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)  	user_list = (struct winbindd_pw *)state->response.extra_data;  	sep = lp_winbind_separator(); -	if (!(ent = state->getpwent_state)) { +	if (!(ent = state->getpwent_state))  		return WINBINDD_ERROR; -	}  	/* Start sending back users */ @@ -540,7 +508,8 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)  			/* No more domains */ -			if (!ent) break; +			if (!ent)  +                                break;  		}  		name_list = ent->sam_entries; @@ -579,11 +548,9 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)  			state->response.length +=   				sizeof(struct winbindd_pw); -		} else { +		} else  			DEBUG(1, ("could not lookup domain user %s\n",  				  domain_user_name)); -		} -		  	}  	/* Out of domains */ @@ -620,10 +587,6 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)  			continue;  		} -		if (!domain_handles_open(domain)) { -			continue; -		} -  		/* Query display info */  		do { @@ -692,5 +655,3 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)  	return WINBINDD_OK;  } - -#endif diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index c5b3c7585b..c257719be1 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -24,39 +24,33 @@  #include "winbindd.h"  #include "sids.h" -#if 0 - -static void winbindd_kill_connections(struct winbindd_domain *domain); -  /* Add a trusted domain to our list of domains */ -static struct winbindd_domain *add_trusted_domain(char *domain_name) +static struct winbindd_domain *add_trusted_domain(char *domain_name, +                                                  DOM_SID *domain_sid)  {      struct winbindd_domain *domain, *tmp;      for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {  	    if (strcmp(domain_name, tmp->name) == 0) { -		    DEBUG(3, ("domain %s already in trusted list\n", +		    DEBUG(3, ("domain %s already in domain list\n",  			      domain_name));  		    return tmp;  	    }      } -    DEBUG(1, ("adding trusted domain %s\n", domain_name)); +    DEBUG(1, ("adding domain %s\n", domain_name));      /* Create new domain entry */ -    if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) { +    if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL)          return NULL; -    }      /* Fill in fields */      ZERO_STRUCTP(domain); - -    if (domain_name) { -        fstrcpy(domain->name, domain_name); -    } +    fstrcpy(domain->name, domain_name); +    sid_copy(&domain->sid, domain_sid);      /* Link to domain list */ @@ -67,42 +61,55 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name)  /* Look up global info for the winbind daemon */ -static BOOL get_trusted_domains(void) +BOOL get_domain_info(void)  {  	uint32 enum_ctx = 0;  	uint32 num_doms = 0;  	char **domains = NULL; -	DOM_SID *sids = NULL; -	BOOL result; +	DOM_SID *sids = NULL, domain_sid; +        NTSTATUS result; +        CLI_POLICY_HND *hnd;  	int i; +        fstring level5_dom;  	DEBUG(1, ("getting trusted domain list\n"));  	/* Add our workgroup - keep handle to look up trusted domains */ -	if (!add_trusted_domain(lp_workgroup())) { -		DEBUG(0, ("could not add record for domain %s\n",  -			  lp_workgroup())); -		return False; -	} + +        if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) +                return False; + +        result = cli_lsa_query_info_policy(hnd->cli, hnd->cli->mem_ctx, +                                           &hnd->pol, 0x05, level5_dom, +                                           &domain_sid); + +        if (!NT_STATUS_IS_OK(result)) +                return False; + +	add_trusted_domain(lp_workgroup(), &domain_sid);  	/* Enumerate list of trusted domains */	 -	result = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx, -				       &num_doms, &domains, &sids); + +        if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) +                return False; + +        result = cli_lsa_enum_trust_dom(hnd->cli, hnd->cli->mem_ctx, +                                        &hnd->pol, &enum_ctx, &num_doms,  +                                        &domains, &sids); -	if (!result || !domains) return False; +        if (!NT_STATUS_IS_OK(result)) +                return False;          /* Add each domain to the trusted domain list */ -	for(i = 0; i < num_doms; i++) { -		if (!add_trusted_domain(domains[i])) { -			DEBUG(0, ("could not add record for domain %s\n",  -				  domains[i])); -			result = False; -		} -	} + +	for(i = 0; i < num_doms; i++) +		add_trusted_domain(domains[i], &sids[i]);  	return True;  } +#if 0 +  /* Open sam and sam domain handles */  static BOOL open_sam_handles(struct winbindd_domain *domain) @@ -408,9 +415,11 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)          return NT_STATUS_IS_OK(result);  } +#if 0 +  /* Lookup domain controller and sid for a domain */ -BOOL get_domain_info(struct winbindd_domain *domain) + BOOL get_domain_info(struct winbindd_domain *domain)  {          fstring sid_str; @@ -433,6 +442,8 @@ BOOL get_domain_info(struct winbindd_domain *domain)          return True;  }         +#endif +  /* Lookup a sid in a domain from a name */  BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, @@ -518,17 +529,31 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,          return False;  } -#if 0 -  /* Lookup user information from a rid */ -BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, -                              uint32 user_rid, SAM_USERINFO_CTR **user_info) +BOOL winbindd_lookup_userinfo(char *domain_name, uint32 user_rid,  +                              SAM_USERINFO_CTR **user_info)  { -	return wb_get_samr_query_userinfo(&domain->sam_dom_handle, 0x15,  -					  user_rid, user_info); +        CLI_POLICY_HND *hnd; +        uint16 info_level = 0x15; +        NTSTATUS result; +        struct winbindd_domain *domain; + +        if (!(domain = find_domain_from_name(domain_name))) +                return False; + +        if (!(hnd = cm_get_sam_user_handle(domain_name, &domain->sid,  +                                           user_rid))) +                return False; + +        result = cli_samr_query_userinfo(hnd->cli, hnd->cli->mem_ctx, +                                         &hnd->pol, info_level, user_info); + +        return NT_STATUS_IS_OK(result);  }                                    +#if 0 +  /* Lookup groups a user is a member of.  I wish Unix had a call like this! */  BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, @@ -587,14 +612,8 @@ struct winbindd_domain *find_domain_from_name(char *domain_name)  	/* Search through list */  	for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { -		if (strcmp(domain_name, tmp->name) == 0) { - -			if (!tmp->got_domain_info) { -				get_domain_info(tmp); -			} - -                        return tmp->got_domain_info ? tmp : NULL; -                } +		if (strcmp(domain_name, tmp->name) == 0) +                        return tmp;          }  	/* Not found */ @@ -609,14 +628,17 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)  	struct winbindd_domain *tmp;  	/* Search through list */ +  	for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {  		if (sid_equal(sid, &tmp->sid)) { -			if (!tmp->got_domain_info) return NULL; +			if (!tmp->got_domain_info)  +                                return NULL;                          return tmp;                  }          }  	/* Not found */ +  	return NULL;  } @@ -704,8 +726,6 @@ BOOL winbindd_param_init(void)      return True;  } -#if 0 -  /* Query display info for a domain.  This returns enough information plus a     bit extra to give an overview of domain users for the User Manager     application. */ @@ -714,8 +734,20 @@ NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,  				 uint32 *start_ndx, uint16 info_level,   				 uint32 *num_entries, SAM_DISPINFO_CTR *ctr)  { -	return wb_samr_query_dispinfo(&domain->sam_dom_handle, start_ndx, -				      info_level, num_entries, ctr); +        CLI_POLICY_HND *hnd; +        NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + +        if (!(hnd = cm_get_sam_dom_handle(domain->name, &domain->sid))) +                return result; + +        result = cli_samr_query_dispinfo(hnd->cli, hnd->cli->mem_ctx, +                                         &hnd->pol, start_ndx, info_level, +                                         num_entries, 0xffff, ctr); + +        if (!NT_STATUS_IS_OK(result)) +                return result; + +        return NT_STATUS_OK;  }  /* Check if a domain is present in a comma-separated list of domains */ @@ -734,8 +766,6 @@ BOOL check_domain_env(char *domain_env, char *domain)  	return False;  } -#endif -  /* Parse a string of the form DOMAIN/user into a domain and a user */  void parse_domain_user(char *domuser, fstring domain, fstring user)  | 
