~ubuntu-branches/ubuntu/precise/samba/precise

« back to all changes in this revision

Viewing changes to source3/passdb/lookup_sid.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
   Copyright (C) Andrew Tridgell         1992-1998
5
5
   Copyright (C) Gerald (Jerry) Carter   2003
6
6
   Copyright (C) Volker Lendecke         2005
7
 
   
 
7
 
8
8
   This program is free software; you can redistribute it and/or modify
9
9
   it under the terms of the GNU General Public License as published by
10
10
   the Free Software Foundation; either version 3 of the License, or
11
11
   (at your option) any later version.
12
 
   
 
12
 
13
13
   This program is distributed in the hope that it will be useful,
14
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
16
   GNU General Public License for more details.
17
 
   
 
17
 
18
18
   You should have received a copy of the GNU General Public License
19
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
20
*/
21
21
 
22
22
#include "includes.h"
 
23
#include "passdb.h"
 
24
#include "../librpc/gen_ndr/ndr_security.h"
 
25
#include "secrets.h"
 
26
#include "memcache.h"
 
27
#include "idmap_cache.h"
 
28
#include "../libcli/security/security.h"
 
29
#include "lib/winbind_util.h"
23
30
 
24
31
/*****************************************************************
25
32
 Dissect a user-provided name into domain, name, sid and type.
32
39
bool lookup_name(TALLOC_CTX *mem_ctx,
33
40
                 const char *full_name, int flags,
34
41
                 const char **ret_domain, const char **ret_name,
35
 
                 DOM_SID *ret_sid, enum lsa_SidType *ret_type)
 
42
                 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
36
43
{
37
44
        char *p;
38
45
        const char *tmp;
39
46
        const char *domain = NULL;
40
47
        const char *name = NULL;
41
48
        uint32 rid;
42
 
        DOM_SID sid;
 
49
        struct dom_sid sid;
43
50
        enum lsa_SidType type;
44
51
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
45
52
 
65
72
                return false;
66
73
        }
67
74
 
68
 
        DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
 
75
        DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
69
76
                full_name, domain, name));
70
77
        DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
71
78
 
75
82
 
76
83
                /* It's our own domain, lookup the name in passdb */
77
84
                if (lookup_global_sam_name(name, flags, &rid, &type)) {
78
 
                        sid_copy(&sid, get_global_sam_sid());
79
 
                        sid_append_rid(&sid, rid);
 
85
                        sid_compose(&sid, get_global_sam_sid(), rid);
80
86
                        goto ok;
81
87
                }
82
88
                TALLOC_FREE(tmp_ctx);
96
102
 
97
103
                /* Explicit request for a name in BUILTIN */
98
104
                if (lookup_builtin_name(name, &rid)) {
99
 
                        sid_copy(&sid, &global_sid_Builtin);
100
 
                        sid_append_rid(&sid, rid);
 
105
                        sid_compose(&sid, &global_sid_Builtin, rid);
101
106
                        type = SID_NAME_ALIAS;
102
107
                        goto ok;
103
108
                }
215
220
            lookup_builtin_name(name, &rid))
216
221
        {
217
222
                domain = talloc_strdup(tmp_ctx, builtin_domain_name());
218
 
                sid_copy(&sid, &global_sid_Builtin);
219
 
                sid_append_rid(&sid, rid);
 
223
                sid_compose(&sid, &global_sid_Builtin, rid);
220
224
                type = SID_NAME_ALIAS;
221
225
                goto ok;
222
226
        }
230
234
            lookup_global_sam_name(name, flags, &rid, &type))
231
235
        {
232
236
                domain = talloc_strdup(tmp_ctx, get_global_sam_name());
233
 
                sid_copy(&sid, get_global_sam_sid());
234
 
                sid_append_rid(&sid, rid);
 
237
                sid_compose(&sid, get_global_sam_sid(), rid);
235
238
                goto ok;
236
239
        }
237
240
 
257
260
         * that (yet), but give it a chance. */
258
261
 
259
262
        if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
260
 
                DOM_SID dom_sid;
261
 
                uint32 tmp_rid;
 
263
                struct dom_sid dom_sid;
262
264
                enum lsa_SidType domain_type;
263
 
                
 
265
 
264
266
                if (type == SID_NAME_DOMAIN) {
265
267
                        /* Swap name and type */
266
268
                        tmp = name; name = domain; domain = tmp;
272
274
                 * domain it figured out itself. Maybe fix that later... */
273
275
 
274
276
                sid_copy(&dom_sid, &sid);
275
 
                sid_split_rid(&dom_sid, &tmp_rid);
 
277
                sid_split_rid(&dom_sid, NULL);
276
278
 
277
279
                if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
278
280
                                        &domain_type) ||
361
363
bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
362
364
                 const char *full_name, int flags,
363
365
                 const char **ret_domain, const char **ret_name,
364
 
                 DOM_SID *ret_sid, enum lsa_SidType *ret_type)
 
366
                 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
365
367
{
366
368
        char *qualified_name;
367
369
        const char *p;
402
404
                                ret_sid, ret_type)) {
403
405
                return true;
404
406
        }
405
 
        
 
407
 
406
408
        /* Finally try with "Unix Users" or "Unix Group" */
407
409
        qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
408
410
                                flags & LOOKUP_NAME_GROUP ?
419
421
}
420
422
 
421
423
static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
422
 
                           const DOM_SID *domain_sid,
 
424
                           const struct dom_sid *domain_sid,
423
425
                           int num_rids, uint32 *rids,
424
426
                           const char **domain_name,
425
427
                           const char **names, enum lsa_SidType *types)
469
471
        return true;
470
472
}
471
473
 
472
 
static bool lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
 
474
static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
473
475
                        int num_rids, uint32_t *rids,
474
476
                        const char **domain_name,
475
477
                        const char ***names, enum lsa_SidType **types)
543
545
 
544
546
        if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
545
547
                for (i=0; i<num_rids; i++) {
546
 
                        DOM_SID sid;
547
 
                        sid_copy(&sid, domain_sid);
548
 
                        sid_append_rid(&sid, rids[i]);
 
548
                        struct dom_sid sid;
 
549
                        sid_compose(&sid, domain_sid, rids[i]);
549
550
                        if (lookup_wellknown_sid(mem_ctx, &sid,
550
551
                                                 domain_name, &(*names)[i])) {
551
552
                                if ((*names)[i] == NULL) {
605
606
 * Is the SID a domain as such? If yes, lookup its name.
606
607
 */
607
608
 
608
 
static bool lookup_as_domain(const DOM_SID *sid, TALLOC_CTX *mem_ctx,
 
609
static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
609
610
                             const char **name)
610
611
{
611
612
        const char *tmp;
656
657
                }
657
658
 
658
659
                for (i=0; i<num_domains; i++) {
659
 
                        if (sid_equal(sid, &domains[i]->sid)) {
 
660
                        if (dom_sid_equal(sid, &domains[i]->sid)) {
660
661
                                *name = talloc_strdup(mem_ctx,
661
662
                                                      domains[i]->name);
662
663
                                return true;
693
694
 * Level 6: Like 4
694
695
 */
695
696
 
696
 
static bool check_dom_sid_to_level(const DOM_SID *sid, int level)
 
697
static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
697
698
{
698
699
        int ret = false;
699
700
 
728
729
 * This attempts to be as efficient as possible: It collects all SIDs
729
730
 * belonging to a domain and hands them in bulk to the appropriate lookup
730
731
 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
731
 
 * *hugely* from this. Winbind is going to be extended with a lookup_rids
732
 
 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
733
 
 * appropriate DC.
 
732
 * *hugely* from this.
734
733
 */
735
734
 
736
735
NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
737
 
                     const DOM_SID **sids, int level,
 
736
                     const struct dom_sid **sids, int level,
738
737
                     struct lsa_dom_info **ret_domains,
739
738
                     struct lsa_name_info **ret_names)
740
739
{
782
781
         */
783
782
 
784
783
        for (i=0; i<num_sids; i++) {
785
 
                DOM_SID sid;
786
 
                uint32 rid;
 
784
                struct dom_sid sid;
 
785
                uint32_t rid = 0;
787
786
                const char *domain_name = NULL;
788
787
 
789
788
                sid_copy(&sid, sids[i]);
801
800
                                result = NT_STATUS_NO_MEMORY;
802
801
                                goto fail;
803
802
                        }
804
 
                                
 
803
 
805
804
                        name_infos[i].rid = 0;
806
805
                        name_infos[i].type = SID_NAME_DOMAIN;
807
806
                        name_infos[i].name = NULL;
835
834
                        if (!dom_infos[j].valid) {
836
835
                                break;
837
836
                        }
838
 
                        if (sid_equal(&sid, &dom_infos[j].sid)) {
 
837
                        if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
839
838
                                break;
840
839
                        }
841
840
                }
920
919
                        result = NT_STATUS_NO_MEMORY;
921
920
                        goto fail;
922
921
                }
923
 
                        
 
922
 
924
923
                for (j=0; j<dom->num_idxs; j++) {
925
924
                        int idx = dom->idxs[j];
926
925
                        name_infos[idx].type = types[j];
953
952
 *THE CANONICAL* convert SID to name function.
954
953
*****************************************************************/  
955
954
 
956
 
bool lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
 
955
bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
957
956
                const char **ret_domain, const char **ret_name,
958
957
                enum lsa_SidType *ret_type)
959
958
{
1017
1016
  Find a SID given a uid.
1018
1017
*****************************************************************/
1019
1018
 
1020
 
static bool fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
 
1019
static bool fetch_sid_from_uid_cache(struct dom_sid *psid, uid_t uid)
1021
1020
{
1022
1021
        DATA_BLOB cache_value;
1023
1022
 
1029
1028
 
1030
1029
        memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1031
1030
        SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1032
 
        SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, NULL, 0));
 
1031
        SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1033
1032
 
1034
1033
        return true;
1035
1034
}
1038
1037
  Find a uid given a SID.
1039
1038
*****************************************************************/
1040
1039
 
1041
 
static bool fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
 
1040
static bool fetch_uid_from_cache( uid_t *puid, const struct dom_sid *psid )
1042
1041
{
1043
1042
        DATA_BLOB cache_value;
1044
1043
 
1045
1044
        if (!memcache_lookup(NULL, SID_UID_CACHE,
1046
 
                             data_blob_const(psid, ndr_size_dom_sid(psid, NULL, 0)),
 
1045
                             data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1047
1046
                             &cache_value)) {
1048
1047
                return false;
1049
1048
        }
1058
1057
 Store uid to SID mapping in cache.
1059
1058
*****************************************************************/
1060
1059
 
1061
 
void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
 
1060
void store_uid_sid_cache(const struct dom_sid *psid, uid_t uid)
1062
1061
{
1063
1062
        memcache_add(NULL, SID_UID_CACHE,
1064
 
                     data_blob_const(psid, ndr_size_dom_sid(psid, NULL, 0)),
 
1063
                     data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1065
1064
                     data_blob_const(&uid, sizeof(uid)));
1066
1065
        memcache_add(NULL, UID_SID_CACHE,
1067
1066
                     data_blob_const(&uid, sizeof(uid)),
1068
 
                     data_blob_const(psid, ndr_size_dom_sid(psid, NULL, 0)));
 
1067
                     data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1069
1068
}
1070
1069
 
1071
1070
/*****************************************************************
1072
1071
  Find a SID given a gid.
1073
1072
*****************************************************************/
1074
1073
 
1075
 
static bool fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
 
1074
static bool fetch_sid_from_gid_cache(struct dom_sid *psid, gid_t gid)
1076
1075
{
1077
1076
        DATA_BLOB cache_value;
1078
1077
 
1084
1083
 
1085
1084
        memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1086
1085
        SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1087
 
        SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, NULL, 0));
 
1086
        SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1088
1087
 
1089
1088
        return true;
1090
1089
}
1093
1092
  Find a gid given a SID.
1094
1093
*****************************************************************/
1095
1094
 
1096
 
static bool fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
 
1095
static bool fetch_gid_from_cache(gid_t *pgid, const struct dom_sid *psid)
1097
1096
{
1098
1097
        DATA_BLOB cache_value;
1099
1098
 
1100
1099
        if (!memcache_lookup(NULL, SID_GID_CACHE,
1101
 
                             data_blob_const(psid, ndr_size_dom_sid(psid, NULL, 0)),
 
1100
                             data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1102
1101
                             &cache_value)) {
1103
1102
                return false;
1104
1103
        }
1113
1112
 Store gid to SID mapping in cache.
1114
1113
*****************************************************************/
1115
1114
 
1116
 
void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
 
1115
void store_gid_sid_cache(const struct dom_sid *psid, gid_t gid)
1117
1116
{
1118
1117
        memcache_add(NULL, SID_GID_CACHE,
1119
 
                     data_blob_const(psid, ndr_size_dom_sid(psid, NULL, 0)),
 
1118
                     data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1120
1119
                     data_blob_const(&gid, sizeof(gid)));
1121
1120
        memcache_add(NULL, GID_SID_CACHE,
1122
1121
                     data_blob_const(&gid, sizeof(gid)),
1123
 
                     data_blob_const(psid, ndr_size_dom_sid(psid, NULL, 0)));
 
1122
                     data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1124
1123
}
1125
1124
 
1126
1125
/*****************************************************************
1127
1126
 *THE LEGACY* convert uid_t to SID function.
1128
1127
*****************************************************************/  
1129
1128
 
1130
 
static void legacy_uid_to_sid(DOM_SID *psid, uid_t uid)
 
1129
static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1131
1130
{
1132
1131
        bool ret;
1133
1132
 
1158
1157
 *THE LEGACY* convert gid_t to SID function.
1159
1158
*****************************************************************/  
1160
1159
 
1161
 
static void legacy_gid_to_sid(DOM_SID *psid, gid_t gid)
 
1160
static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1162
1161
{
1163
1162
        bool ret;
1164
1163
 
1172
1171
                /* This is a mapped group */
1173
1172
                goto done;
1174
1173
        }
1175
 
        
 
1174
 
1176
1175
        /* This is an unmapped group */
1177
1176
 
1178
1177
        gid_to_unix_groups_sid(gid, psid);
1189
1188
 *THE LEGACY* convert SID to uid function.
1190
1189
*****************************************************************/  
1191
1190
 
1192
 
static bool legacy_sid_to_uid(const DOM_SID *psid, uid_t *puid)
 
1191
static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1193
1192
{
1194
1193
        enum lsa_SidType type;
1195
 
        uint32 rid;
1196
1194
 
1197
 
        if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
 
1195
        if (sid_check_is_in_our_domain(psid)) {
1198
1196
                union unid_t id;
1199
1197
                bool ret;
1200
1198
 
1233
1231
 Group mapping is used for gids that maps to Wellknown SIDs
1234
1232
*****************************************************************/  
1235
1233
 
1236
 
static bool legacy_sid_to_gid(const DOM_SID *psid, gid_t *pgid)
 
1234
static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1237
1235
{
1238
 
        uint32 rid;
1239
1236
        GROUP_MAP map;
1240
1237
        union unid_t id;
1241
1238
        enum lsa_SidType type;
1257
1254
                return false;
1258
1255
        }
1259
1256
 
1260
 
        if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
 
1257
        if (sid_check_is_in_our_domain(psid)) {
1261
1258
                bool ret;
1262
1259
 
1263
1260
                become_root();
1275
1272
                        *pgid = id.gid;
1276
1273
                        goto done;
1277
1274
                }
1278
 
        
 
1275
 
1279
1276
                /* This was ours, but it was not mapped.  Fail */
1280
1277
        }
1281
1278
 
1282
1279
        DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1283
1280
                  sid_string_dbg(psid)));
1284
1281
        return false;
1285
 
        
 
1282
 
1286
1283
 done:
1287
1284
        DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid),
1288
1285
                  (unsigned int)*pgid ));
1296
1293
 *THE CANONICAL* convert uid_t to SID function.
1297
1294
*****************************************************************/  
1298
1295
 
1299
 
void uid_to_sid(DOM_SID *psid, uid_t uid)
 
1296
void uid_to_sid(struct dom_sid *psid, uid_t uid)
1300
1297
{
1301
1298
        bool expired = true;
1302
1299
        bool ret;
1349
1346
 *THE CANONICAL* convert gid_t to SID function.
1350
1347
*****************************************************************/  
1351
1348
 
1352
 
void gid_to_sid(DOM_SID *psid, gid_t gid)
 
1349
void gid_to_sid(struct dom_sid *psid, gid_t gid)
1353
1350
{
1354
1351
        bool expired = true;
1355
1352
        bool ret;
1398
1395
        return;
1399
1396
}
1400
1397
 
 
1398
bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids,
 
1399
                      struct wbcUnixId *ids)
 
1400
{
 
1401
        struct wbcDomainSid *wbc_sids = NULL;
 
1402
        struct wbcUnixId *wbc_ids = NULL;
 
1403
        uint32_t i, num_not_cached;
 
1404
        wbcErr err;
 
1405
        bool ret = false;
 
1406
 
 
1407
        wbc_sids = TALLOC_ARRAY(talloc_tos(), struct wbcDomainSid, num_sids);
 
1408
        if (wbc_sids == NULL) {
 
1409
                return false;
 
1410
        }
 
1411
 
 
1412
        num_not_cached = 0;
 
1413
 
 
1414
        for (i=0; i<num_sids; i++) {
 
1415
                bool expired;
 
1416
                uint32_t rid;
 
1417
 
 
1418
                if (fetch_uid_from_cache(&ids[i].id.uid, &sids[i])) {
 
1419
                        ids[i].type = WBC_ID_TYPE_UID;
 
1420
                        continue;
 
1421
                }
 
1422
                if (fetch_gid_from_cache(&ids[i].id.gid, &sids[i])) {
 
1423
                        ids[i].type = WBC_ID_TYPE_GID;
 
1424
                        continue;
 
1425
                }
 
1426
                if (sid_peek_check_rid(&global_sid_Unix_Users,
 
1427
                                       &sids[i], &rid)) {
 
1428
                        ids[i].type = WBC_ID_TYPE_UID;
 
1429
                        ids[i].id.uid = rid;
 
1430
                        continue;
 
1431
                }
 
1432
                if (sid_peek_check_rid(&global_sid_Unix_Groups,
 
1433
                                       &sids[i], &rid)) {
 
1434
                        ids[i].type = WBC_ID_TYPE_GID;
 
1435
                        ids[i].id.gid = rid;
 
1436
                        continue;
 
1437
                }
 
1438
                if (idmap_cache_find_sid2uid(&sids[i], &ids[i].id.uid,
 
1439
                                             &expired)
 
1440
                    && !expired) {
 
1441
                        ids[i].type = WBC_ID_TYPE_UID;
 
1442
                        continue;
 
1443
                }
 
1444
                if (idmap_cache_find_sid2gid(&sids[i], &ids[i].id.gid,
 
1445
                                             &expired)
 
1446
                    && !expired) {
 
1447
                        ids[i].type = WBC_ID_TYPE_GID;
 
1448
                        continue;
 
1449
                }
 
1450
                ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
 
1451
                memcpy(&wbc_sids[num_not_cached], &sids[i],
 
1452
                       ndr_size_dom_sid(&sids[i], 0));
 
1453
                num_not_cached += 1;
 
1454
        }
 
1455
        if (num_not_cached == 0) {
 
1456
                goto done;
 
1457
        }
 
1458
        wbc_ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId, num_not_cached);
 
1459
        if (wbc_ids == NULL) {
 
1460
                goto fail;
 
1461
        }
 
1462
        for (i=0; i<num_not_cached; i++) {
 
1463
                wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
 
1464
        }
 
1465
        err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
 
1466
        if (!WBC_ERROR_IS_OK(err)) {
 
1467
                DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
 
1468
                           wbcErrorString(err)));
 
1469
        }
 
1470
 
 
1471
        num_not_cached = 0;
 
1472
 
 
1473
        for (i=0; i<num_sids; i++) {
 
1474
                if (ids[i].type == WBC_ID_TYPE_NOT_SPECIFIED) {
 
1475
                        ids[i] = wbc_ids[num_not_cached];
 
1476
                        num_not_cached += 1;
 
1477
                }
 
1478
        }
 
1479
 
 
1480
        for (i=0; i<num_sids; i++) {
 
1481
                if (ids[i].type != WBC_ID_TYPE_NOT_SPECIFIED) {
 
1482
                        continue;
 
1483
                }
 
1484
                if (legacy_sid_to_gid(&sids[i], &ids[i].id.gid)) {
 
1485
                        ids[i].type = WBC_ID_TYPE_GID;
 
1486
                        continue;
 
1487
                }
 
1488
                if (legacy_sid_to_uid(&sids[i], &ids[i].id.uid)) {
 
1489
                        ids[i].type = WBC_ID_TYPE_UID;
 
1490
                        continue;
 
1491
                }
 
1492
        }
 
1493
done:
 
1494
        ret = true;
 
1495
fail:
 
1496
        TALLOC_FREE(wbc_ids);
 
1497
        TALLOC_FREE(wbc_sids);
 
1498
        return ret;
 
1499
}
 
1500
 
1401
1501
/*****************************************************************
1402
1502
 *THE CANONICAL* convert SID to uid function.
1403
1503
*****************************************************************/  
1404
1504
 
1405
 
bool sid_to_uid(const DOM_SID *psid, uid_t *puid)
 
1505
bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1406
1506
{
1407
1507
        bool expired = true;
1408
1508
        bool ret;
1464
1564
 Group mapping is used for gids that maps to Wellknown SIDs
1465
1565
*****************************************************************/  
1466
1566
 
1467
 
bool sid_to_gid(const DOM_SID *psid, gid_t *pgid)
 
1567
bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1468
1568
{
1469
1569
        bool expired = true;
1470
1570
        bool ret;
1520
1620
        store_gid_sid_cache(psid, *pgid);
1521
1621
        return true;
1522
1622
}
 
1623
 
 
1624
/**
 
1625
 * @brief This function gets the primary group SID mapping the primary
 
1626
 *        GID of the user as obtained by an actual getpwnam() call.
 
1627
 *        This is necessary to avoid issues with arbitrary group SIDs
 
1628
 *        stored in passdb. We try as hard as we can to get the SID
 
1629
 *        corresponding to the GID, including trying group mapping.
 
1630
 *        If nothing else works, we will force "Domain Users" as the
 
1631
 *        primary group.
 
1632
 *        This is needed because we must always be able to lookup the
 
1633
 *        primary group SID, so we cannot settle for an arbitrary SID.
 
1634
 *
 
1635
 *        This call can be expensive. Use with moderation.
 
1636
 *        If you have a "samu" struct around use pdb_get_group_sid()
 
1637
 *        instead as it does properly cache results.
 
1638
 *
 
1639
 * @param mem_ctx[in]     The memory context iused to allocate the result.
 
1640
 * @param username[in]    The user's name
 
1641
 * @param _pwd[in|out]    If available, pass in user's passwd struct.
 
1642
 *                        It will contain a tallocated passwd if NULL was
 
1643
 *                        passed in.
 
1644
 * @param _group_sid[out] The user's Primary Group SID
 
1645
 *
 
1646
 * @return NTSTATUS error code.
 
1647
 */
 
1648
NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
 
1649
                                const char *username,
 
1650
                                struct passwd **_pwd,
 
1651
                                struct dom_sid **_group_sid)
 
1652
{
 
1653
        TALLOC_CTX *tmp_ctx;
 
1654
        bool need_lookup_sid = false;
 
1655
        struct dom_sid *group_sid;
 
1656
        struct passwd *pwd = *_pwd;
 
1657
 
 
1658
        tmp_ctx = talloc_new(mem_ctx);
 
1659
        if (!tmp_ctx) {
 
1660
                return NT_STATUS_NO_MEMORY;
 
1661
        }
 
1662
 
 
1663
        if (!pwd) {
 
1664
                pwd = Get_Pwnam_alloc(mem_ctx, username);
 
1665
                if (!pwd) {
 
1666
                        DEBUG(0, ("Failed to find a Unix account for %s",
 
1667
                                  username));
 
1668
                        TALLOC_FREE(tmp_ctx);
 
1669
                        return NT_STATUS_NO_SUCH_USER;
 
1670
                }
 
1671
        }
 
1672
 
 
1673
        group_sid = talloc_zero(mem_ctx, struct dom_sid);
 
1674
        if (!group_sid) {
 
1675
                TALLOC_FREE(tmp_ctx);
 
1676
                return NT_STATUS_NO_MEMORY;
 
1677
        }
 
1678
 
 
1679
        gid_to_sid(group_sid, pwd->pw_gid);
 
1680
        if (!is_null_sid(group_sid)) {
 
1681
                struct dom_sid domain_sid;
 
1682
                uint32_t rid;
 
1683
 
 
1684
                /* We need a sid within our domain */
 
1685
                sid_copy(&domain_sid, group_sid);
 
1686
                sid_split_rid(&domain_sid, &rid);
 
1687
                if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
 
1688
                        /*
 
1689
                         * As shortcut for the expensive lookup_sid call
 
1690
                         * compare the domain sid part
 
1691
                         */
 
1692
                        switch (rid) {
 
1693
                        case DOMAIN_RID_ADMINS:
 
1694
                        case DOMAIN_RID_USERS:
 
1695
                                goto done;
 
1696
                        default:
 
1697
                                need_lookup_sid = true;
 
1698
                                break;
 
1699
                        }
 
1700
                } else {
 
1701
                        /* Try group mapping */
 
1702
                        ZERO_STRUCTP(group_sid);
 
1703
                        if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
 
1704
                                need_lookup_sid = true;
 
1705
                        }
 
1706
                }
 
1707
        }
 
1708
 
 
1709
        /* We must verify that this is a valid SID that resolves to a
 
1710
         * group of the correct type */
 
1711
        if (need_lookup_sid) {
 
1712
                enum lsa_SidType type = SID_NAME_UNKNOWN;
 
1713
                bool lookup_ret;
 
1714
 
 
1715
                DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
 
1716
                           sid_string_dbg(group_sid), username));
 
1717
 
 
1718
                /* Now check that it's actually a domain group and
 
1719
                 * not something else */
 
1720
                lookup_ret = lookup_sid(tmp_ctx, group_sid,
 
1721
                                        NULL, NULL, &type);
 
1722
 
 
1723
                if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
 
1724
                        goto done;
 
1725
                }
 
1726
 
 
1727
                DEBUG(3, ("Primary group %s for user %s is"
 
1728
                          " a %s and not a domain group\n",
 
1729
                          sid_string_dbg(group_sid), username,
 
1730
                          sid_type_lookup(type)));
 
1731
        }
 
1732
 
 
1733
        /* Everything else, failed.
 
1734
         * Just set it to the 'Domain Users' RID of 513 which will
 
1735
           always resolve to a name */
 
1736
        DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
 
1737
                  username));
 
1738
 
 
1739
        sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
 
1740
 
 
1741
done:
 
1742
        *_pwd = talloc_move(mem_ctx, &pwd);
 
1743
        *_group_sid = talloc_move(mem_ctx, &group_sid);
 
1744
        TALLOC_FREE(tmp_ctx);
 
1745
        return NT_STATUS_OK;
 
1746
}
 
1747
 
 
1748
bool delete_uid_cache(uid_t puid)
 
1749
{
 
1750
        DATA_BLOB uid = data_blob_const(&puid, sizeof(puid));
 
1751
        DATA_BLOB sid;
 
1752
 
 
1753
        if (!memcache_lookup(NULL, UID_SID_CACHE, uid, &sid)) {
 
1754
                DEBUG(3, ("UID %d is not memcached!\n", (int)puid));
 
1755
                return false;
 
1756
        }
 
1757
        DEBUG(3, ("Delete mapping UID %d <-> %s from memcache\n", (int)puid,
 
1758
                  sid_string_dbg((struct dom_sid*)sid.data)));
 
1759
        memcache_delete(NULL, SID_UID_CACHE, sid);
 
1760
        memcache_delete(NULL, UID_SID_CACHE, uid);
 
1761
        return true;
 
1762
}
 
1763
 
 
1764
bool delete_gid_cache(gid_t pgid)
 
1765
{
 
1766
        DATA_BLOB gid = data_blob_const(&pgid, sizeof(pgid));
 
1767
        DATA_BLOB sid;
 
1768
        if (!memcache_lookup(NULL, GID_SID_CACHE, gid, &sid)) {
 
1769
                DEBUG(3, ("GID %d is not memcached!\n", (int)pgid));
 
1770
                return false;
 
1771
        }
 
1772
        DEBUG(3, ("Delete mapping GID %d <-> %s from memcache\n", (int)pgid,
 
1773
                  sid_string_dbg((struct dom_sid*)sid.data)));
 
1774
        memcache_delete(NULL, SID_GID_CACHE, sid);
 
1775
        memcache_delete(NULL, GID_SID_CACHE, gid);
 
1776
        return true;
 
1777
}
 
1778
 
 
1779
bool delete_sid_cache(const struct dom_sid* psid)
 
1780
{
 
1781
        DATA_BLOB sid = data_blob_const(psid, ndr_size_dom_sid(psid, 0));
 
1782
        DATA_BLOB id;
 
1783
        if (memcache_lookup(NULL, SID_GID_CACHE, sid, &id)) {
 
1784
                DEBUG(3, ("Delete mapping %s <-> GID %d from memcache\n",
 
1785
                          sid_string_dbg(psid), *(int*)id.data));
 
1786
                memcache_delete(NULL, SID_GID_CACHE, sid);
 
1787
                memcache_delete(NULL, GID_SID_CACHE, id);
 
1788
        } else if (memcache_lookup(NULL, SID_UID_CACHE, sid, &id)) {
 
1789
                DEBUG(3, ("Delete mapping %s <-> UID %d from memcache\n",
 
1790
                          sid_string_dbg(psid), *(int*)id.data));
 
1791
                memcache_delete(NULL, SID_UID_CACHE, sid);
 
1792
                memcache_delete(NULL, UID_SID_CACHE, id);
 
1793
        } else {
 
1794
                DEBUG(3, ("SID %s is not memcached!\n", sid_string_dbg(psid)));
 
1795
                return false;
 
1796
        }
 
1797
        return true;
 
1798
}
 
1799
 
 
1800
void flush_gid_cache(void)
 
1801
{
 
1802
        DEBUG(3, ("Flush GID <-> SID memcache\n"));
 
1803
        memcache_flush(NULL, SID_GID_CACHE);
 
1804
        memcache_flush(NULL, GID_SID_CACHE);
 
1805
}
 
1806
 
 
1807
void flush_uid_cache(void)
 
1808
{
 
1809
        DEBUG(3, ("Flush UID <-> SID memcache\n"));
 
1810
        memcache_flush(NULL, SID_UID_CACHE);
 
1811
        memcache_flush(NULL, UID_SID_CACHE);
 
1812
}