Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * ID mapping: abstract r/w new-mapping mechanism
5 : *
6 : * Copyright (C) Michael Adam 2010
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 3 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License
19 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "winbindd.h"
24 : #include "idmap.h"
25 : #include "idmap_rw.h"
26 : #include "libcli/security/dom_sid.h"
27 :
28 : #undef DBGC_CLASS
29 : #define DBGC_CLASS DBGC_IDMAP
30 :
31 0 : NTSTATUS idmap_rw_new_mapping(struct idmap_domain *dom,
32 : struct idmap_rw_ops *ops,
33 : struct id_map *map)
34 : {
35 : struct dom_sid_buf buf;
36 : NTSTATUS status;
37 :
38 0 : if (map == NULL) {
39 0 : return NT_STATUS_INVALID_PARAMETER;
40 : }
41 :
42 0 : if (map->sid == NULL) {
43 0 : return NT_STATUS_INVALID_PARAMETER;
44 : }
45 :
46 0 : switch (map->xid.type) {
47 0 : case ID_TYPE_NOT_SPECIFIED:
48 : /*
49 : * We need to know if we need a user or group mapping.
50 : * Ask the winbindd parent to provide a valid type hint.
51 : */
52 0 : DBG_INFO("%s ID_TYPE_NOT_SPECIFIED => ID_REQUIRE_TYPE\n",
53 : dom_sid_str_buf(map->sid, &buf));
54 0 : map->status = ID_REQUIRE_TYPE;
55 0 : return NT_STATUS_SOME_NOT_MAPPED;
56 :
57 0 : case ID_TYPE_BOTH:
58 : /*
59 : * For now we still require
60 : * an explicit type as hint
61 : * and don't support ID_TYPE_BOTH
62 : */
63 0 : DBG_INFO("%s ID_TYPE_BOTH => ID_REQUIRE_TYPE\n",
64 : dom_sid_str_buf(map->sid, &buf));
65 0 : map->status = ID_REQUIRE_TYPE;
66 0 : return NT_STATUS_SOME_NOT_MAPPED;
67 :
68 0 : case ID_TYPE_UID:
69 0 : break;
70 :
71 0 : case ID_TYPE_GID:
72 0 : break;
73 :
74 0 : default:
75 0 : return NT_STATUS_INVALID_PARAMETER;
76 : }
77 :
78 0 : status = ops->get_new_id(dom, &map->xid);
79 :
80 0 : if (!NT_STATUS_IS_OK(status)) {
81 0 : DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status)));
82 0 : return status;
83 : }
84 :
85 0 : DEBUG(10, ("Setting mapping: %s <-> %s %lu\n",
86 : dom_sid_str_buf(map->sid, &buf),
87 : (map->xid.type == ID_TYPE_UID) ? "UID" : "GID",
88 : (unsigned long)map->xid.id));
89 :
90 0 : map->status = ID_MAPPED;
91 0 : status = ops->set_mapping(dom, map);
92 :
93 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
94 : struct id_map *ids[2];
95 0 : DEBUG(5, ("Mapping for %s exists - retrying to map sid\n",
96 : dom_sid_str_buf(map->sid, &buf)));
97 0 : ids[0] = map;
98 0 : ids[1] = NULL;
99 0 : status = dom->methods->sids_to_unixids(dom, ids);
100 : }
101 :
102 0 : if (!NT_STATUS_IS_OK(status)) {
103 0 : DEBUG(3, ("Could not store the new mapping: %s\n",
104 : nt_errstr(status)));
105 0 : return status;
106 : }
107 :
108 0 : return NT_STATUS_OK;
109 : }
|