Fresh meat in trusted domains code:
authorRafal Szczesniak <mimir@samba.org>
Fri, 14 Mar 2003 17:12:40 +0000 (17:12 +0000)
committerRafal Szczesniak <mimir@samba.org>
Fri, 14 Mar 2003 17:12:40 +0000 (17:12 +0000)
 - packing/unpacking utility functions for trusted domain
   password struct; can be used to prepare buffer to store
   in secrets.tdb or (soon) passdb backend
 - similiar functions for DOM_SID
 - respectively modified secrets_(fetch|store) routines
 - new auth mapping code utilising introduced is_trusted_domain
   function
 - added tdb (un)packing of single bytes

Rafal

source/auth/auth_util.c
source/include/secrets.h
source/passdb/secrets.c
source/tdb/tdbutil.c

index 7d85153bd0e04e32ea114295dccaf4e0eab7ac75..a6ad2b883bcd165f2b04ab2eecda179e0373e328 100644 (file)
@@ -227,27 +227,13 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
 
                domain = client_domain;
 
-               if ((smb_name) && (*smb_name)) { /* Don't do this for guests */
-                       char *user = NULL;
-                       if (asprintf(&user, "%s%s%s", 
-                                client_domain, lp_winbind_separator(), 
-                                smb_name) < 0) {
-                               DEBUG(0, ("make_user_info_map: asprintf() failed!\n"));
-                               return NT_STATUS_NO_MEMORY;
-                       }
-
-                       DEBUG(5, ("make_user_info_map: testing for user %s\n", user));
-                       
-                       if (Get_Pwnam(user) == NULL) {
-                               DEBUG(5, ("make_user_info_map: test for user %s failed\n", user));
-                               domain = lp_workgroup();
-                               DEBUG(5, ("make_user_info_map: trusted domain %s doesn't appear to exist, using %s\n", 
-                                         client_domain, domain));
-                       } else {
-                               DEBUG(5, ("make_user_info_map: using trusted domain %s\n", domain));
-                       }
-                       SAFE_FREE(user);
+               if (is_trusted_domain(domain)) {
+                       return make_user_info(user_info, smb_name, internal_username,
+                                             client_domain, domain, wksta_name,
+                                             lm_pwd, nt_pwd, plaintext, ntlmssp_flags,
+                                             encrypted);
                }
+
        } else {
                domain = lp_workgroup();
        }
index 183b29d7a8a594baf9cb826cc70b9db6da8e6f93..07faf28d439dcd7eb56da4fbf6bf3dba2651d0cd 100644 (file)
@@ -57,14 +57,14 @@ struct machine_acct_pass {
 /*
  * storage structure for trusted domain
  */
-struct trusted_dom_pass {
+typedef struct trusted_dom_pass {
        size_t uni_name_len;
        smb_ucs2_t uni_name[32]; /* unicode domain name */
        size_t pass_len;
        fstring pass;           /* trust relationship's password */
        time_t mod_time;
        DOM_SID domain_sid;     /* remote domain's sid */
-};
+} TRUSTED_DOM_PASS;
 
 /*
  * trusted domain entry/entries returned by secrets_get_trusted_domains
index 2b944a99413163f20a064394659dc7a86db1ad5d..4b0913a62433e232837c4d9e735ad9d581f48437 100644 (file)
@@ -265,38 +265,44 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
 ************************************************************************/
 
 BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
-                                          DOM_SID *sid, time_t *pass_last_set_time)
+                                           DOM_SID *sid, time_t *pass_last_set_time)
 {
-       struct trusted_dom_pass *pass;
+       struct trusted_dom_pass pass;
        size_t size;
+       
+       /* unpacking structures */
+       char* pass_buf;
+       int pass_len = 0;
+
+       ZERO_STRUCT(pass);
 
        /* fetching trusted domain password structure */
-       if (!(pass = secrets_fetch(trustdom_keystr(domain), &size))) {
+       if (!(pass_buf = secrets_fetch(trustdom_keystr(domain), &size))) {
                DEBUG(5, ("secrets_fetch failed!\n"));
                return False;
        }
 
-       if (size != sizeof(*pass)) {
-               DEBUG(0, ("secrets were of incorrect size!\n"));
+       /* unpack trusted domain password */
+       pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
+       if (pass_len != size) {
+               DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
                return False;
        }
-
+                       
        /* the trust's password */      
        if (pwd) {
-               *pwd = strdup(pass->pass);
+               *pwd = strdup(pass.pass);
                if (!*pwd) {
                        return False;
                }
        }
 
        /* last change time */
-       if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
+       if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
 
        /* domain sid */
-       memcpy(&sid, &(pass->domain_sid), sizeof(sid));
-       
-       SAFE_FREE(pass);
-       
+       sid_copy(sid, &pass.domain_sid);
+               
        return True;
 }
 
@@ -315,7 +321,7 @@ BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
 }
 
 /**
- * Routine to set the password for trusted domain
+ * Routine to store the password for trusted domain
  *
  * @param domain remote domain name
  * @param pwd plain text password of trust relationship
@@ -325,12 +331,17 @@ BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
  **/
 
 BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_dom_name,
-                                          size_t uni_name_len, const char* pwd,
-                                          DOM_SID sid)
-{
+                                           size_t uni_name_len, const char* pwd,
+                                           DOM_SID sid)
+{      
+       /* packing structures */
+       pstring pass_buf;
+       int pass_len = 0;
+       int pass_buf_len = sizeof(pass_buf);
+       
        struct trusted_dom_pass pass;
        ZERO_STRUCT(pass);
-
+       
        /* unicode domain name and its length */
        if (!uni_dom_name)
                return False;
@@ -346,9 +357,11 @@ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_d
        fstrcpy(pass.pass, pwd);
 
        /* domain sid */
-       memcpy(&(pass.domain_sid), &sid, sizeof(sid));
+       sid_copy(&pass.domain_sid, &sid);
+       
+       pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
 
-       return secrets_store(trustdom_keystr(domain), (void *)&pass, sizeof(pass));
+       return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
 }
 
 /************************************************************************
@@ -475,9 +488,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in
        char *pattern;
        unsigned int start_idx;
        uint32 idx = 0;
-       size_t size;
+       size_t size, packed_size = 0;
        fstring dom_name;
-       struct trusted_dom_pass *pass;
+       char *packed_pass;
+       struct trusted_dom_pass *pass = talloc_zero(ctx, sizeof(struct trusted_dom_pass));
        NTSTATUS status;
 
        if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
@@ -505,7 +519,7 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in
         */
        status = NT_STATUS_NO_MORE_ENTRIES;
 
-       /* searching for keys in sectrets db -- way to go ... */
+       /* searching for keys in secrets db -- way to go ... */
        for (k = keys; k; k = k->next) {
                char *secrets_key;
                
@@ -516,14 +530,20 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in
                        return NT_STATUS_NO_MEMORY;
                }
                                
-               pass = secrets_fetch(secrets_key, &size);
-               
-               if (size != sizeof(*pass)) {
+               packed_pass = secrets_fetch(secrets_key, &size);
+               packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass);
+
+               if (size != packed_size) {
                        DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key));
                        SAFE_FREE(pass);
-                       continue;
+                       if (size) SAFE_FREE(packed_pass);
+
+                       return NT_STATUS_UNSUCCESSFUL;
                }
                
+               /* packed representation isn't needed anymore */
+               SAFE_FREE(packed_pass);
+               
                pull_ucs2_fstring(dom_name, pass->uni_name);
                DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
                           idx, dom_name, sid_string_static(&pass->domain_sid)));
@@ -569,10 +589,7 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in
                                   start_idx, max_num_domains));
                }
                
-               idx++;
-               
-               /* free returned tdb record */
-               SAFE_FREE(pass);
+               idx++;          
        }
        
        DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
index 0d8f6128cc5f8e7d0cec89d3b2822227026bdf7d..b153d442bd6f267506b2eb589a1d40454a5aee2e 100644 (file)
@@ -42,7 +42,7 @@ static void gotalarm_sig(void)
 static TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
 {
        TDB_DATA ret;
-       ret.dptr = dptr;
+       ret.dptr = smb_xstrdup(dptr);
        ret.dsize = dsize;
        return ret;
 }
@@ -387,6 +387,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv
 size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 {
        va_list ap;
+       uint8 bt;
        uint16 w;
        uint32 d;
        int i;
@@ -402,40 +403,46 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 
        while (*fmt) {
                switch ((c = *fmt++)) {
-               case 'w':
+               case 'b': /* unsigned 8-bit integer */
+                       len = 1;
+                       bt = (uint8)va_arg(ap, int);
+                       if (bufsize >= len)
+                               SSVAL(buf, 0, bt);
+                       break;
+               case 'w': /* unsigned 16-bit integer */
                        len = 2;
                        w = (uint16)va_arg(ap, int);
                        if (bufsize >= len)
                                SSVAL(buf, 0, w);
                        break;
-               case 'd':
+               case 'd': /* signed 32-bit integer (standard int in most systems) */
                        len = 4;
                        d = va_arg(ap, uint32);
                        if (bufsize >= len)
                                SIVAL(buf, 0, d);
                        break;
-               case 'p':
+               case 'p': /* pointer */
                        len = 4;
                        p = va_arg(ap, void *);
                        d = p?1:0;
                        if (bufsize >= len)
                                SIVAL(buf, 0, d);
                        break;
-               case 'P':
+               case 'P': /* null-terminated string */
                        s = va_arg(ap,char *);
                        w = strlen(s);
                        len = w + 1;
                        if (bufsize >= len)
                                memcpy(buf, s, len);
                        break;
-               case 'f':
+               case 'f': /* null-terminated string */
                        s = va_arg(ap,char *);
                        w = strlen(s);
                        len = w + 1;
                        if (bufsize >= len)
                                memcpy(buf, s, len);
                        break;
-               case 'B':
+               case 'B': /* fixed-length string */
                        i = va_arg(ap, int);
                        s = va_arg(ap, char *);
                        len = 4+i;
@@ -471,6 +478,7 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...)
 int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
 {
        va_list ap;
+       uint8 *bt;
        uint16 *w;
        uint32 *d;
        int len;
@@ -486,6 +494,13 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
        
        while (*fmt) {
                switch ((c=*fmt++)) {
+               case 'b':
+                       len = 1;
+                       bt = va_arg(ap, uint8 *);
+                       if (bufsize < len)
+                               goto no_space;
+                       *bt = SVAL(buf, 0);
+                       break;
                case 'w':
                        len = 2;
                        w = va_arg(ap, uint16 *);
@@ -563,6 +578,130 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
        return -1;
 }
 
+
+/**
+ * Pack SID passed by pointer
+ *
+ * @param pack_buf pointer to buffer which is to be filled with packed data
+ * @param bufsize size of packing buffer
+ * @param sid pointer to sid to be packed
+ *
+ * @return length of the packed representation of the whole structure
+ **/
+size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid)
+{
+       int idx;
+       size_t len = 0;
+       
+       if (!sid || !pack_buf) return -1;
+       
+       len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
+                       sid->num_auths);
+       
+       for (idx = 0; idx < 6; idx++) {
+               len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]);
+       }
+       
+       for (idx = 0; idx < MAXSUBAUTHS; idx++) {
+               len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]);
+       }
+       
+       return len;
+}
+
+
+/**
+ * Unpack SID into a pointer
+ *
+ * @param pack_buf pointer to buffer with packed representation
+ * @param bufsize size of the buffer
+ * @param sid pointer to sid structure to be filled with unpacked data
+ *
+ * @return size of structure unpacked from buffer
+ **/
+size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid)
+{
+       int idx, len = 0;
+       
+       if (!sid || !pack_buf) return -1;
+
+       len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
+                         &sid->sid_rev_num, &sid->num_auths);
+                         
+       for (idx = 0; idx < 6; idx++) {
+               len += tdb_unpack(pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]);
+       }
+       
+       for (idx = 0; idx < MAXSUBAUTHS; idx++) {
+               len += tdb_unpack(pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]);
+       }
+       
+       return len;
+}
+
+
+/**
+ * Pack TRUSTED_DOM_PASS passed by pointer
+ *
+ * @param pack_buf pointer to buffer which is to be filled with packed data
+ * @param bufsize size of the buffer
+ * @param pass pointer to trusted domain password to be packed
+ *
+ * @return length of the packed representation of the whole structure
+ **/
+size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass)
+{
+       int idx, len = 0;
+       
+       if (!pack_buf || !pass) return -1;
+       
+       /* packing unicode domain name and password */
+       len += tdb_pack(pack_buf + len, bufsize - len, "d", pass->uni_name_len);
+       
+       for (idx = 0; idx < 32; idx++)
+               len +=  tdb_pack(pack_buf + len, bufsize - len, "w", pass->uni_name[idx]);
+       
+       len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len,
+                            pass->pass, pass->mod_time);
+
+       /* packing SID structure */
+       len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid);
+
+       return len;
+}
+
+
+/**
+ * Unpack TRUSTED_DOM_PASS passed by pointer
+ *
+ * @param pack_buf pointer to buffer with packed representation
+ * @param bufsize size of the buffer
+ * @param pass pointer to trusted domain password to be filled with unpacked data
+ *
+ * @return size of structure unpacked from buffer
+ **/
+size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass)
+{
+       int idx, len = 0;
+       
+       if (!pack_buf || !pass) return -1;
+
+       /* unpack unicode domain name and plaintext password */
+       len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
+       
+       for (idx = 0; idx < 32; idx++)
+               len +=  tdb_unpack(pack_buf + len, bufsize - len, "w", &pass->uni_name[idx]);
+
+       len += tdb_unpack(pack_buf + len, bufsize - len, "dPd", &pass->pass_len, &pass->pass,
+                         &pass->mod_time);
+       
+       /* unpack domain sid */
+       len += tdb_sid_unpack(pack_buf + len, bufsize - len, &pass->domain_sid);
+       
+       return len;     
+}
+
+
 /****************************************************************************
  Log tdb messages via DEBUG().
 ****************************************************************************/