The beginnings of alternative backends for winbindd
authorAndrew Tridgell <tridge@samba.org>
Sat, 1 Dec 2001 12:31:43 +0000 (12:31 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 1 Dec 2001 12:31:43 +0000 (12:31 +0000)
This just splits off the dispinfo call behind a methods structure.
I'll split off a few more functions soon, then we will be ready for
LDAP replacement methods

source/include/config.h.in
source/lib/util_unistr.c
source/nsswitch/winbindd.h
source/nsswitch/winbindd_cm.c
source/nsswitch/winbindd_proto.h
source/nsswitch/winbindd_user.c
source/nsswitch/winbindd_util.c

index 930eee6084bd5bc6f7728891a8b1debe9a5f896c..635c634e116fc8996db549fe22ebc29042549e96 100644 (file)
@@ -1,4 +1,4 @@
-/* include/config.h.in.  Generated automatically from configure.in by autoheader.  */
+/* include/config.h.in.  Generated automatically from configure.in by autoheader 2.13.  */
 
 /* Define if on AIX 3.
    System headers sometimes define this.
index d2d23dafa5afe107742e6133d849a2f9ee3a165b..fc29ca8dc207f60f2e3ad0bcc3384d693da87378 100644 (file)
@@ -164,6 +164,23 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
 }
 
 
+/*******************************************************************
+ duplicate a UNISTR2 string into a null terminated char*
+ using a talloc context
+********************************************************************/
+char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
+{
+       char *s;
+       int maxlen = (str->uni_str_len+1)*4;
+       if (!str->buffer) return NULL;
+       s = (char *)talloc(ctx, maxlen); /* convervative */
+       if (!s) return NULL;
+       pull_ucs2(NULL, s, str->buffer, maxlen, str->uni_str_len*2, 
+                 STR_NOALIGN);
+       return s;
+}
+
+
 /*******************************************************************
 Return a number stored in a buffer
 ********************************************************************/
index 1380d5cc8832fb5b5c5e9af4c511a110fc9e0649..c4a7c82bc60c886c5cd4cd742fab44d54e93b7ad 100644 (file)
@@ -77,11 +77,33 @@ struct winbindd_state {
 
 extern struct winbindd_state server_state;  /* Server information */
 
-/* Structures to hold per domain information */
+typedef struct {
+       char *acct_name;
+       char *full_name;
+       uint32 user_rid;
+       uint32 group_rid; /* primary group */
+} WINBIND_DISPINFO;
+
+/* per-domain methods. This is how LDAP vs RPC is selected
+   This will eventually be the sole entry point to all the methods,
+   I'm just starting small
+ */
+struct winbindd_methods {
+       NTSTATUS (*query_dispinfo)(struct winbindd_domain *domain,
+                                  TALLOC_CTX *mem_ctx,
+                                  uint32 *start_ndx, uint32 *num_entries, 
+                                  WINBIND_DISPINFO **info);
+
 
+};
+
+/* Structures to hold per domain information */
 struct winbindd_domain {
        fstring name;                          /* Domain name */        
        DOM_SID sid;                           /* SID for this domain */
+       struct winbindd_methods *methods;      /* lookup methods for
+                                                  this domain (LDAP or
+                                                  RPC) */
        struct winbindd_domain *prev, *next;   /* Linked list info */
 };
 
index f11d86d4c1b318fb5bfa39e61d721f07fbe71e9c..987b28e09cc392c3dc265a453d78b0e875e7c2f9 100644 (file)
@@ -73,7 +73,7 @@ struct winbindd_cm_conn {
        POLICY_HND pol;
 };
 
-struct winbindd_cm_conn *cm_conns = NULL;
+static struct winbindd_cm_conn *cm_conns = NULL;
 
 /* Get a domain controller name.  Cache positive and negative lookups so we
    don't go to the network too often when something is badly broken. */
index 7c3326ce36ece27077f1b77fceabf3394e040465..fc8377697a9de52bfdbaa644af47fcf285347ad1 100644 (file)
@@ -152,8 +152,8 @@ void free_getent_state(struct getent_state *state);
 BOOL winbindd_param_init(void);
 NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
                                  TALLOC_CTX *mem_ctx,
-                                uint32 *start_ndx, uint16 info_level
-                                uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
+                                uint32 *start_ndx, uint32 *num_entries
+                                WINBIND_DISPINFO **info);
 BOOL check_domain_env(char *domain_env, char *domain);
 void parse_domain_user(char *domuser, fstring domain, fstring user);
 #endif /* _PROTO_H_ */
index 853350fd19c14e985baeb6c5551f7e11ed300af5..2cc64cb56504970567e84703194123c2bf2db9db 100644 (file)
@@ -377,12 +377,11 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
 {
        NTSTATUS status;
        uint32 num_entries;
-       SAM_DISPINFO_1 info1;
-       SAM_DISPINFO_CTR ctr;
+       WINBIND_DISPINFO *info;
        struct getpwent_user *name_list = NULL;
-       uint32 group_rid;
        BOOL result = False;
        TALLOC_CTX *mem_ctx;
+       struct winbindd_methods *methods;
 
        if (ent->got_all_sam_entries)
                return False;
@@ -390,10 +389,7 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
        if (!(mem_ctx = talloc_init()))
                return False;
 
-       ZERO_STRUCT(info1);
-       ZERO_STRUCT(ctr);
-
-       ctr.sam.info1 = &info1;
+       methods = ent->domain->methods;
 
 #if 0
        /* Look in cache for entries, else get them direct */
@@ -406,14 +402,6 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
        }
 #endif
 
-       /* For the moment we set the primary group for every user to be the
-          Domain Users group.  There are serious problems with determining
-          the actual primary group for large domains.  This should really
-          be made into a 'winbind force group' smb.conf parameter or
-          something like that. */ 
-
-       group_rid = DOMAIN_GROUP_RID_USERS;
-
        /* Free any existing user info */
 
        SAFE_FREE(ent->sam_entries);
@@ -426,9 +414,9 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
                                        
                num_entries = 0;
 
-               status = winbindd_query_dispinfo(ent->domain, mem_ctx,
-                                                &ent->dispinfo_ndx, 1,
-                                                &num_entries, &ctr);
+               status = methods->query_dispinfo(ent->domain, mem_ctx,
+                                                &ent->dispinfo_ndx, 
+                                                &num_entries, &info);
                
                if (num_entries) {
                        struct getpwent_user *tnl;
@@ -447,26 +435,23 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
                }
 
                for (i = 0; i < num_entries; i++) {
-
                        /* Store account name and gecos */
-
-                       unistr2_to_ascii(
-                               name_list[ent->num_sam_entries + i].name, 
-                               &info1.str[i].uni_acct_name, 
-                               sizeof(fstring));
-
-                       unistr2_to_ascii(
-                               name_list[ent->num_sam_entries + i].gecos, 
-                               &info1.str[i].uni_full_name, 
-                               sizeof(fstring));
+                       if (!info[i].acct_name) {
+                               fstrcpy(name_list[ent->num_sam_entries + i].name, "");
+                       } else {
+                               fstrcpy(name_list[ent->num_sam_entries + i].name, 
+                                       info[i].acct_name); 
+                       }
+                       if (!info[i].full_name) {
+                               fstrcpy(name_list[ent->num_sam_entries + i].gecos, "");
+                       } else {
+                               fstrcpy(name_list[ent->num_sam_entries + i].gecos, 
+                                       info[i].full_name); 
+                       }
 
                        /* User and group ids */
-
-                       name_list[ent->num_sam_entries + i].user_rid =
-                               info1.sam[i].rid_user;
-
-                       name_list[ent->num_sam_entries + i].
-                               group_rid = group_rid;
+                       name_list[ent->num_sam_entries+i].user_rid = info[i].user_rid;
+                       name_list[ent->num_sam_entries+i].group_rid = info[i].group_rid;
                }
                
                ent->num_sam_entries += num_entries;
@@ -615,8 +600,7 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
 enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
 {
        struct winbindd_domain *domain;
-       SAM_DISPINFO_CTR ctr;
-       SAM_DISPINFO_1 info1;
+       WINBIND_DISPINFO *info;
        uint32 num_entries = 0, total_entries = 0;
        char *ted, *extra_data = NULL;
        int extra_data_len = 0;
@@ -630,14 +614,13 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
 
        /* Enumerate over trusted domains */
 
-       ctr.sam.info1 = &info1;
-
        if (domain_list == NULL)
                get_domain_info();
 
        for (domain = domain_list; domain; domain = domain->next) {
                NTSTATUS status;
                uint32 start_ndx = 0;
+               struct winbindd_methods *methods;
 
                /* Skip domains other than WINBINDD_DOMAIN environment
                   variable */ 
@@ -646,20 +629,20 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
                    !check_domain_env(state->request.domain, domain->name))
                        continue;
 
+               methods = domain->methods;
+
                /* Query display info */
 
                do {
                        int i;
 
-                       status = winbindd_query_dispinfo(
-                                domain, mem_ctx, &start_ndx, 
-                                1, &num_entries, &ctr);
+                       status = methods->query_dispinfo(domain, mem_ctx, &start_ndx, 
+                                                        &num_entries, &info);
 
                        if (num_entries == 0)
                                continue;
 
                        /* Allocate some memory for extra data */
-
                        total_entries += num_entries;
                        
                        ted = Realloc(extra_data, sizeof(fstring) * 
@@ -675,26 +658,22 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
                        /* Pack user list into extra data fields */
                        
                        for (i = 0; i < num_entries; i++) {
-                               UNISTR2 *uni_acct_name;
                                fstring acct_name, name;
 
-                               /* Convert unistring to ascii */
-                               
-                               uni_acct_name = &ctr.sam.info1->str[i]. 
-                                       uni_acct_name;
-                               unistr2_to_ascii(acct_name, uni_acct_name,
-                                                sizeof(acct_name) - 1);
+                               if (!info[i].acct_name) {
+                                       fstrcpy(acct_name, "");
+                               } else {
+                                       fstrcpy(acct_name, info[i].acct_name);
+                               }
                                                  
                                slprintf(name, sizeof(name) - 1, "%s%s%s",
                                         domain->name, lp_winbind_separator(),
                                         acct_name);
 
                                /* Append to extra data */
-                       
                                memcpy(&extra_data[extra_data_len], name, 
                                       strlen(name));
                                extra_data_len += strlen(name);
-                               
                                extra_data[extra_data_len++] = ',';
                        }   
                } while (NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES));
index 777b3cdac24f1e67bcdbee5238b46c2ffc450d86..41eb8b9d287d0ea550df6f9880e9be803ba18365 100644 (file)
@@ -40,9 +40,12 @@ static const fstring name_deadbeef = "<deadbeef>";
 
 
 /* Globals for domain list stuff */
-
 struct winbindd_domain *domain_list = NULL;
 
+static struct winbindd_methods msrpc_methods = {
+       winbindd_query_dispinfo
+};
+
 /* Given a domain name, return the struct winbindd domain info for it 
    if it is actually working. */
 
@@ -89,7 +92,8 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
 /* Add a trusted domain to our list of domains */
 
 static struct winbindd_domain *add_trusted_domain(char *domain_name,
-                                                  DOM_SID *domain_sid)
+                                                  DOM_SID *domain_sid,
+                                                 struct winbindd_methods *methods)
 {
        struct winbindd_domain *domain, *tmp;
         
@@ -112,7 +116,8 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
        ZERO_STRUCTP(domain);
        fstrcpy(domain->name, domain_name);
        sid_copy(&domain->sid, domain_sid);
-        
+        domain->methods = methods;
+
        /* Link to domain list */
         
        DLIST_ADD(domain_list, domain);
@@ -150,7 +155,7 @@ BOOL get_domain_info(void)
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
-       add_trusted_domain(lp_workgroup(), &domain_sid);
+       add_trusted_domain(lp_workgroup(), &domain_sid, &msrpc_methods);
        
        /* Enumerate list of trusted domains */ 
 
@@ -166,7 +171,7 @@ BOOL get_domain_info(void)
        /* Add each domain to the trusted domain list */
 
        for(i = 0; i < num_doms; i++)
-               add_trusted_domain(domains[i], &sids[i]);
+               add_trusted_domain(domains[i], &sids[i], &msrpc_methods);
 
        rv = True;      
 
@@ -790,14 +795,17 @@ BOOL winbindd_param_init(void)
 
 NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
                                  TALLOC_CTX *mem_ctx,
-                                uint32 *start_ndx, uint16 info_level
-                                uint32 *num_entries, SAM_DISPINFO_CTR *ctr)
+                                uint32 *start_ndx, uint32 *num_entries
+                                WINBIND_DISPINFO **info)
 {
        CLI_POLICY_HND *hnd;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        POLICY_HND dom_pol;
        BOOL got_dom_pol = False;
        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+       SAM_DISPINFO_CTR ctr;
+       SAM_DISPINFO_1 info1;
+       int i;
 
        /* Get sam handle */
 
@@ -814,11 +822,30 @@ NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
 
        got_dom_pol = True;
 
-       /* Query display info */
+       ctr.sam.info1 = &info1;
 
+       /* Query display info level 1 */
        result = cli_samr_query_dispinfo(hnd->cli, mem_ctx,
-                                       &dom_pol, start_ndx, info_level,
-                                       num_entries, 0xffff, ctr);
+                                       &dom_pol, start_ndx, 1,
+                                       num_entries, 0xffff, &ctr);
+
+       /* now map the result into the WINBIND_DISPINFO structure */
+       (*info) = (WINBIND_DISPINFO *)talloc(mem_ctx, (*num_entries)*sizeof(WINBIND_DISPINFO));
+       if (!(*info)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0;i<*num_entries;i++) {
+               (*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[i].uni_acct_name);
+               (*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[i].uni_full_name);
+               (*info)[i].user_rid = info1.sam[i].rid_user;
+               /* For the moment we set the primary group for every user to be the
+                  Domain Users group.  There are serious problems with determining
+                  the actual primary group for large domains.  This should really
+                  be made into a 'winbind force group' smb.conf parameter or
+                  something like that. */ 
+               (*info)[i].group_rid = DOMAIN_GROUP_RID_USERS;
+       }
 
  done: