Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/winbindd/winbindd_util.c

    r480 r745  
    2323#include "includes.h"
    2424#include "winbindd.h"
     25#include "secrets.h"
     26#include "../libcli/security/security.h"
     27#include "../libcli/auth/pam_errors.h"
     28#include "passdb/machine_sid.h"
    2529
    2630#undef DBGC_CLASS
     
    2832
    2933extern struct winbindd_methods cache_methods;
    30 extern struct winbindd_methods builtin_passdb_methods;
    31 extern struct winbindd_methods sam_passdb_methods;
    32 
    3334
    3435/**
    35  * @file winbindd_util.c
     36 * @file winbindd_util.cq
    3637 *
    3738 * Winbind daemon for NT domain authentication nss module.
     
    5960/* Free all entries in the trusted domain list */
    6061
    61 void free_domain_list(void)
     62static void free_domain_list(void)
    6263{
    6364        struct winbindd_domain *domain = _domain_list;
     
    7273}
    7374
    74 static bool is_internal_domain(const DOM_SID *sid)
     75static bool is_internal_domain(const struct dom_sid *sid)
    7576{
    7677        if (sid == NULL)
     
    8081}
    8182
    82 static bool is_in_internal_domain(const DOM_SID *sid)
     83static bool is_in_internal_domain(const struct dom_sid *sid)
    8384{
    8485        if (sid == NULL)
     
    9293static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
    9394                                                  struct winbindd_methods *methods,
    94                                                   const DOM_SID *sid)
     95                                                  const struct dom_sid *sid)
    9596{
    9697        struct winbindd_domain *domain;
     
    138139                        }
    139140
    140                         if (sid_equal(sid, &domain->sid)) {
     141                        if (dom_sid_equal(sid, &domain->sid)) {
    141142                                break;
    142143                        }
     
    144145        }
    145146
    146         /* See if we found a match.  Check if we need to update the
    147            SID. */
    148 
    149         if ( domain && sid) {
    150                 if ( sid_equal( &domain->sid, &global_sid_NULL ) )
     147        if (domain != NULL) {
     148                /*
     149                 * We found a match. Possibly update the SID
     150                 */
     151                if ((sid != NULL)
     152                    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
    151153                        sid_copy( &domain->sid, sid );
    152 
     154                }
    153155                return domain;
    154156        }
     
    162164
    163165        ZERO_STRUCTP(domain);
     166
     167        domain->children = SMB_MALLOC_ARRAY(
     168                struct winbindd_child, lp_winbind_max_domain_connections());
     169        if (domain->children == NULL) {
     170                SAFE_FREE(domain);
     171                return NULL;
     172        }
     173        memset(domain->children, 0,
     174               sizeof(struct winbindd_child)
     175               * lp_winbind_max_domain_connections());
    164176
    165177        fstrcpy(domain->name, domain_name);
     
    224236}
    225237
     238bool domain_is_forest_root(const struct winbindd_domain *domain)
     239{
     240        const uint32_t fr_flags =
     241                (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
     242
     243        return ((domain->domain_flags & fr_flags) == fr_flags);
     244}
     245
    226246/********************************************************************
    227247  rescan our domains looking for new trusted domains
     
    229249
    230250struct trustdom_state {
    231         TALLOC_CTX *mem_ctx;
    232         bool primary;
    233         bool forest_root;
    234         struct winbindd_response *response;
     251        struct winbindd_domain *domain;
     252        struct winbindd_request request;
    235253};
    236254
    237 static void trustdom_recv(void *private_data, bool success);
     255static void trustdom_list_done(struct tevent_req *req);
    238256static void rescan_forest_root_trusts( void );
    239257static void rescan_forest_trusts( void );
     
    241259static void add_trusted_domains( struct winbindd_domain *domain )
    242260{
    243         TALLOC_CTX *mem_ctx;
    244         struct winbindd_request *request;
     261        struct trustdom_state *state;
     262        struct tevent_req *req;
     263
     264        state = TALLOC_ZERO_P(NULL, struct trustdom_state);
     265        if (state == NULL) {
     266                DEBUG(0, ("talloc failed\n"));
     267                return;
     268        }
     269        state->domain = domain;
     270
     271        state->request.length = sizeof(state->request);
     272        state->request.cmd = WINBINDD_LIST_TRUSTDOM;
     273
     274        req = wb_domain_request_send(state, winbind_event_context(),
     275                                     domain, &state->request);
     276        if (req == NULL) {
     277                DEBUG(1, ("wb_domain_request_send failed\n"));
     278                TALLOC_FREE(state);
     279                return;
     280        }
     281        tevent_req_set_callback(req, trustdom_list_done, state);
     282}
     283
     284static void trustdom_list_done(struct tevent_req *req)
     285{
     286        struct trustdom_state *state = tevent_req_callback_data(
     287                req, struct trustdom_state);
    245288        struct winbindd_response *response;
    246         uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
    247 
    248         struct trustdom_state *state;
    249 
    250         mem_ctx = talloc_init("add_trusted_domains");
    251         if (mem_ctx == NULL) {
    252                 DEBUG(0, ("talloc_init failed\n"));
    253                 return;
    254         }
    255 
    256         request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request);
    257         response = TALLOC_P(mem_ctx, struct winbindd_response);
    258         state = TALLOC_P(mem_ctx, struct trustdom_state);
    259 
    260         if ((request == NULL) || (response == NULL) || (state == NULL)) {
    261                 DEBUG(0, ("talloc failed\n"));
    262                 talloc_destroy(mem_ctx);
    263                 return;
    264         }
    265 
    266         state->mem_ctx = mem_ctx;
    267         state->response = response;
    268 
    269         /* Flags used to know how to continue the forest trust search */
    270 
    271         state->primary = domain->primary;
    272         state->forest_root = ((domain->domain_flags & fr_flags) == fr_flags );
    273 
    274         request->length = sizeof(*request);
    275         request->cmd = WINBINDD_LIST_TRUSTDOM;
    276 
    277         async_domain_request(mem_ctx, domain, request, response,
    278                              trustdom_recv, state);
    279 }
    280 
    281 static void trustdom_recv(void *private_data, bool success)
    282 {
    283         struct trustdom_state *state =
    284                 talloc_get_type_abort(private_data, struct trustdom_state);
    285         struct winbindd_response *response = state->response;
     289        int res, err;
    286290        char *p;
    287291
    288         if ((!success) || (response->result != WINBINDD_OK)) {
     292        res = wb_domain_request_recv(req, state, &response, &err);
     293        if ((res == -1) || (response->result != WINBINDD_OK)) {
    289294                DEBUG(1, ("Could not receive trustdoms\n"));
    290                 talloc_destroy(state->mem_ctx);
     295                TALLOC_FREE(state);
    291296                return;
    292297        }
     
    296301        while ((p != NULL) && (*p != '\0')) {
    297302                char *q, *sidstr, *alt_name;
    298                 DOM_SID sid;
     303                struct dom_sid sid;
    299304                struct winbindd_domain *domain;
    300305                char *alternate_name = NULL;
     
    346351                                                    &sid);
    347352                        if (domain) {
    348                                 setup_domain_child(domain,
    349                                                    &domain->child);
     353                                setup_domain_child(domain);
    350354                        }
    351355                }
     
    363367        */
    364368
    365         if ( state->primary ) {
     369        if (state->domain->primary) {
    366370                /* If this is our primary domain and we are not in the
    367371                   forest root, we have to scan the root trusts first */
    368372
    369                 if ( !state->forest_root )
     373                if (!domain_is_forest_root(state->domain))
    370374                        rescan_forest_root_trusts();
    371375                else
    372376                        rescan_forest_trusts();
    373377
    374         } else if ( state->forest_root ) {
     378        } else if (domain_is_forest_root(state->domain)) {
    375379                /* Once we have done root forest trust search, we can
    376380                   go on to search the trusted forests */
     
    379383        }
    380384
    381         talloc_destroy(state->mem_ctx);
     385        TALLOC_FREE(state);
    382386
    383387        return;
     
    424428                                                &dom_list[i].sid );
    425429                        if (d != NULL) {
    426                                 setup_domain_child(d, &d->child);
     430                                setup_domain_child(d);
    427431                        }
    428432                }
     
    496500                                                        &dom_list[i].sid );
    497501                                if (d != NULL) {
    498                                         setup_domain_child(d, &d->child);
     502                                        setup_domain_child(d);
    499503                                }
    500504                        }
     
    606610        /* BUILTIN domain */
    607611
    608         domain = add_trusted_domain("BUILTIN", NULL, &builtin_passdb_methods,
     612        domain = add_trusted_domain("BUILTIN", NULL, &cache_methods,
    609613                                    &global_sid_Builtin);
    610614        if (domain) {
    611                 setup_domain_child(domain,
    612                                    &domain->child);
     615                setup_domain_child(domain);
    613616        }
    614617
     
    616619
    617620        domain = add_trusted_domain(get_global_sam_name(), NULL,
    618                                     &sam_passdb_methods, get_global_sam_sid());
     621                                    &cache_methods, get_global_sam_sid());
    619622        if (domain) {
    620623                if ( role != ROLE_DOMAIN_MEMBER ) {
    621624                        domain->primary = True;
    622625                }
    623                 setup_domain_child(domain,
    624                                    &domain->child);
     626                setup_domain_child(domain);
    625627        }
    626628
     
    628630
    629631        if ( role == ROLE_DOMAIN_MEMBER ) {
    630                 DOM_SID our_sid;
     632                struct dom_sid our_sid;
    631633
    632634                if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) {
     
    639641                if (domain) {
    640642                        domain->primary = True;
    641                         setup_domain_child(domain,
    642                                            &domain->child);
     643                        setup_domain_child(domain);
    643644
    644645                        /* Even in the parent winbindd we'll need to
     
    653654
    654655        return True;
    655 }
    656 
    657 void check_domain_trusted( const char *name, const DOM_SID *user_sid )
    658 {
    659         struct winbindd_domain *domain;
    660         DOM_SID dom_sid;
    661         uint32 rid;
    662 
    663         /* Check if we even care */
    664 
    665         if (!lp_allow_trusted_domains())
    666                 return;
    667 
    668         domain = find_domain_from_name_noinit( name );
    669         if ( domain )
    670                 return;
    671 
    672         sid_copy( &dom_sid, user_sid );
    673         if ( !sid_split_rid( &dom_sid, &rid ) )
    674                 return;
    675 
    676         /* add the newly discovered trusted domain */
    677 
    678         domain = add_trusted_domain( name, NULL, &cache_methods,
    679                                      &dom_sid);
    680 
    681         if ( !domain )
    682                 return;
    683 
    684         /* assume this is a trust from a one-way transitive
    685            forest trust */
    686 
    687         domain->active_directory = True;
    688         domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND;
    689         domain->domain_type  = NETR_TRUST_TYPE_UPLEVEL;
    690         domain->internal = False;
    691         domain->online = True;
    692 
    693         setup_domain_child(domain,
    694                            &domain->child);
    695 
    696         wcache_tdc_add_domain( domain );
    697 
    698         return;
    699656}
    700657
     
    747704/* Given a domain sid, return the struct winbindd domain info for it */
    748705
    749 struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID *sid)
     706struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid)
    750707{
    751708        struct winbindd_domain *domain;
     
    754711
    755712        for (domain = domain_list(); domain != NULL; domain = domain->next) {
    756                 if (sid_compare_domain(sid, &domain->sid) == 0)
     713                if (dom_sid_compare_domain(sid, &domain->sid) == 0)
    757714                        return domain;
    758715        }
     
    765722/* Given a domain sid, return the struct winbindd domain info for it */
    766723
    767 struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid)
     724struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid)
    768725{
    769726        struct winbindd_domain *domain;
     
    799756        struct winbindd_domain *ours = find_our_domain();
    800757
    801         if ( !ours )
     758        if (ours->forest_name[0] == '\0') {
    802759                return NULL;
    803 
    804         if ( strlen(ours->forest_name) == 0 )
    805                 return NULL;
     760        }
    806761
    807762        return find_domain_from_name( ours->forest_name );
     
    810765struct winbindd_domain *find_builtin_domain(void)
    811766{
    812         DOM_SID sid;
    813767        struct winbindd_domain *domain;
    814768
    815         string_to_sid(&sid, "S-1-5-32");
    816         domain = find_domain_from_sid(&sid);
    817 
     769        domain = find_domain_from_sid(&global_sid_Builtin);
    818770        if (domain == NULL) {
    819771                smb_panic("Could not find BUILTIN domain");
     
    825777/* Find the appropriate domain to lookup a name or SID */
    826778
    827 struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid)
     779struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid)
    828780{
    829781        /* SIDs in the S-1-22-{1,2} domain should be handled by our passdb */
     
    943895}
    944896
    945 /* add a domain user name to a buffer */
    946 void parse_add_domuser(void *buf, char *domuser, int *len)
    947 {
    948         fstring domain;
    949         char *p, *user;
    950 
    951         user = domuser;
    952         p = strchr(domuser, *lp_winbind_separator());
    953 
    954         if (p) {
    955 
    956                 fstrcpy(domain, domuser);
    957                 domain[PTR_DIFF(p, domuser)] = 0;
    958                 p++;
    959 
    960                 if (assume_domain(domain)) {
    961 
    962                         user = p;
    963                         *len -= (PTR_DIFF(p, domuser));
    964                 }
    965         }
    966 
    967         safe_strcpy((char *)buf, user, *len);
    968 }
    969 
    970897/* Ensure an incoming username from NSS is fully qualified. Replace the
    971898   incoming fstring with DOMAIN <separator> user. Returns the same
     
    1046973
    1047974/*
    1048  * Winbindd socket accessor functions
    1049  */
    1050 
    1051 const char *get_winbind_pipe_dir(void)
    1052 {
    1053         return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR);
    1054 }
    1055 
    1056 char *get_winbind_priv_pipe_dir(void)
    1057 {
    1058         return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
    1059 }
    1060 
    1061 /* Open the winbindd socket */
    1062 
    1063 static int _winbindd_socket = -1;
    1064 static int _winbindd_priv_socket = -1;
    1065 
    1066 int open_winbindd_socket(void)
    1067 {
    1068         if (_winbindd_socket == -1) {
    1069                 _winbindd_socket = create_pipe_sock(
    1070                         get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
    1071                 DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
    1072                            _winbindd_socket));
    1073         }
    1074 
    1075         return _winbindd_socket;
    1076 }
    1077 
    1078 int open_winbindd_priv_socket(void)
    1079 {
    1080         if (_winbindd_priv_socket == -1) {
    1081                 _winbindd_priv_socket = create_pipe_sock(
    1082                         get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
    1083                 DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
    1084                            _winbindd_priv_socket));
    1085         }
    1086 
    1087         return _winbindd_priv_socket;
    1088 }
    1089 
    1090 /*
    1091975 * Client list accessor functions
    1092976 */
     
    11181002}
    11191003
    1120 /* Close all open clients */
    1121 
    1122 void winbindd_kill_all_clients(void)
    1123 {
    1124         struct winbindd_cli_state *cl = winbindd_client_list();
    1125 
    1126         DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));
    1127 
    1128         while (cl) {
    1129                 struct winbindd_cli_state *next;
    1130 
    1131                 next = cl->next;
    1132                 winbindd_remove_client(cl);
    1133                 cl = next;
    1134         }
    1135 }
    1136 
    11371004/* Return number of open clients */
    11381005
     
    11441011NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
    11451012                                  TALLOC_CTX *mem_ctx,
    1146                                   const DOM_SID *user_sid,
    1147                                   uint32 *p_num_groups, DOM_SID **user_sids)
     1013                                  const struct dom_sid *user_sid,
     1014                                  uint32_t *p_num_groups, struct dom_sid **user_sids)
    11481015{
    11491016        struct netr_SamInfo3 *info3 = NULL;
    11501017        NTSTATUS status = NT_STATUS_NO_MEMORY;
    1151         size_t num_groups = 0;
     1018        uint32_t num_groups = 0;
    11521019
    11531020        DEBUG(3,(": lookup_usergroups_cached\n"));
     
    14791346        return !domain->online;
    14801347}
     1348
     1349bool is_domain_online(const struct winbindd_domain *domain)
     1350{
     1351        return !is_domain_offline(domain);
     1352}
     1353
     1354bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
     1355                   struct dom_sid **sids, uint32_t *num_sids)
     1356{
     1357        const char *p;
     1358
     1359        p = sidstr;
     1360        if (p == NULL)
     1361                return False;
     1362
     1363        while (p[0] != '\0') {
     1364                struct dom_sid sid;
     1365                const char *q = NULL;
     1366
     1367                if (!dom_sid_parse_endp(p, &sid, &q)) {
     1368                        DEBUG(1, ("Could not parse sid %s\n", p));
     1369                        return false;
     1370                }
     1371                if ((q == NULL) || (q[0] != '\n')) {
     1372                        DEBUG(1, ("Got invalid sidstr: %s\n", p));
     1373                        return false;
     1374                }
     1375                if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,
     1376                                                      num_sids)))
     1377                {
     1378                        return False;
     1379                }
     1380                p = q+1;
     1381        }
     1382        return True;
     1383}
Note: See TracChangeset for help on using the changeset viewer.