root/source3/winbindd/winbindd_sid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. winbindd_lookupsid
  2. lookupsid_recv
  3. winbindd_lookupname
  4. lookupname_recv
  5. winbindd_lookuprids
  6. sid2uid_recv
  7. sid2uid_lookupsid_recv
  8. winbindd_sid_to_uid
  9. sid2gid_recv
  10. sid2gid_lookupsid_recv
  11. winbindd_sid_to_gid
  12. set_mapping_recv
  13. winbindd_set_mapping
  14. remove_mapping_recv
  15. winbindd_remove_mapping
  16. set_hwm_recv
  17. winbindd_set_hwm
  18. uid2sid_recv
  19. winbindd_uid_to_sid
  20. gid2sid_recv
  21. winbindd_gid_to_sid
  22. winbindd_allocate_uid
  23. winbindd_dual_allocate_uid
  24. winbindd_allocate_gid
  25. winbindd_dual_allocate_gid

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    Winbind daemon - sid related functions
   5 
   6    Copyright (C) Tim Potter 2000
   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 
  25 #undef DBGC_CLASS
  26 #define DBGC_CLASS DBGC_WINBIND
  27 
  28 /* Convert a string  */
  29 
  30 static void lookupsid_recv(void *private_data, bool success,
  31                            const char *dom_name, const char *name,
  32                            enum lsa_SidType type);
  33 
  34 void winbindd_lookupsid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
  35 {
  36         DOM_SID sid;
  37 
  38         /* Ensure null termination */
  39         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
  40 
  41         DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, 
  42                   state->request.data.sid));
  43 
  44         if (!string_to_sid(&sid, state->request.data.sid)) {
  45                 DEBUG(5, ("%s not a SID\n", state->request.data.sid));
  46                 request_error(state);
  47                 return;
  48         }
  49 
  50         winbindd_lookupsid_async(state->mem_ctx, &sid, lookupsid_recv, state);
  51 }
  52 
  53 static void lookupsid_recv(void *private_data, bool success,
     /* [<][>][^][v][top][bottom][index][help] */
  54                            const char *dom_name, const char *name,
  55                            enum lsa_SidType type)
  56 {
  57         struct winbindd_cli_state *state =
  58                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
  59 
  60         if (!success) {
  61                 DEBUG(5, ("lookupsid returned an error\n"));
  62                 request_error(state);
  63                 return;
  64         }
  65 
  66         fstrcpy(state->response.data.name.dom_name, dom_name);
  67         fstrcpy(state->response.data.name.name, name);
  68         state->response.data.name.type = type;
  69         request_ok(state);
  70 }
  71 
  72 /**
  73  * Look up the SID for a qualified name.  
  74  **/
  75 
  76 static void lookupname_recv(void *private_data, bool success,
  77                             const DOM_SID *sid, enum lsa_SidType type);
  78 
  79 void winbindd_lookupname(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
  80 {
  81         char *name_domain, *name_user;
  82         char *p;
  83 
  84         /* Ensure null termination */
  85         state->request.data.name.dom_name[sizeof(state->request.data.name.dom_name)-1]='\0';
  86 
  87         /* Ensure null termination */
  88         state->request.data.name.name[sizeof(state->request.data.name.name)-1]='\0';
  89 
  90         /* cope with the name being a fully qualified name */
  91         p = strstr(state->request.data.name.name, lp_winbind_separator());
  92         if (p) {
  93                 *p = 0;
  94                 name_domain = state->request.data.name.name;
  95                 name_user = p+1;
  96         } else if ((p = strchr(state->request.data.name.name, '@')) != NULL) {
  97                 /* upn */
  98                 name_domain = p + 1;
  99                 *p = 0;
 100                 name_user = state->request.data.name.name;
 101         } else {
 102                 name_domain = state->request.data.name.dom_name;
 103                 name_user = state->request.data.name.name;
 104         }
 105 
 106         DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
 107                   name_domain, lp_winbind_separator(), name_user));
 108 
 109         winbindd_lookupname_async(state->mem_ctx, name_domain, name_user,
 110                                   lookupname_recv, WINBINDD_LOOKUPNAME, 
 111                                   state);
 112 }
 113 
 114 static void lookupname_recv(void *private_data, bool success,
     /* [<][>][^][v][top][bottom][index][help] */
 115                             const DOM_SID *sid, enum lsa_SidType type)
 116 {
 117         struct winbindd_cli_state *state =
 118                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 119 
 120         if (!success) {
 121                 DEBUG(5, ("lookupname returned an error\n"));
 122                 request_error(state);
 123                 return;
 124         }
 125 
 126         sid_to_fstring(state->response.data.sid.sid, sid);
 127         state->response.data.sid.type = type;
 128         request_ok(state);
 129         return;
 130 }
 131 
 132 void winbindd_lookuprids(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 133 {
 134         struct winbindd_domain *domain;
 135         DOM_SID domain_sid;
 136         
 137         /* Ensure null termination */
 138         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
 139 
 140         DEBUG(10, ("lookup_rids: %s\n", state->request.data.sid));
 141 
 142         if (!string_to_sid(&domain_sid, state->request.data.sid)) {
 143                 DEBUG(5, ("Could not convert %s to SID\n",
 144                           state->request.data.sid));
 145                 request_error(state);
 146                 return;
 147         }
 148 
 149         domain = find_lookup_domain_from_sid(&domain_sid);
 150         if (domain == NULL) {
 151                 DEBUG(10, ("Could not find domain for name %s\n",
 152                            state->request.domain_name));
 153                 request_error(state);
 154                 return;
 155         }
 156 
 157         sendto_domain(state, domain);
 158 }
 159 
 160 /* Convert a sid to a uid.  We assume we only have one rid attached to the
 161    sid. */
 162 
 163 static void sid2uid_recv(void *private_data, bool success, uid_t uid)
     /* [<][>][^][v][top][bottom][index][help] */
 164 {
 165         struct winbindd_cli_state *state =
 166                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 167         struct dom_sid sid;
 168 
 169         string_to_sid(&sid, state->request.data.sid);
 170 
 171         if (!success) {
 172                 DEBUG(5, ("Could not convert sid %s\n",
 173                           state->request.data.sid));
 174                 request_error(state);
 175                 return;
 176         }
 177 
 178         state->response.data.uid = uid;
 179         request_ok(state);
 180 }
 181 
 182 static void sid2uid_lookupsid_recv( void *private_data, bool success, 
     /* [<][>][^][v][top][bottom][index][help] */
 183                                     const char *domain_name, 
 184                                     const char *name, 
 185                                     enum lsa_SidType type)
 186 {
 187         struct winbindd_cli_state *state =
 188                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 189         DOM_SID sid;
 190 
 191         if (!string_to_sid(&sid, state->request.data.sid)) {
 192                 DEBUG(1, ("sid2uid_lookupsid_recv: Could not get convert sid "
 193                           "%s from string\n", state->request.data.sid));
 194                 request_error(state);
 195                 return;
 196         }
 197 
 198         if (!success) {
 199                 DEBUG(5, ("sid2uid_lookupsid_recv Could not convert get sid type for %s\n",
 200                           state->request.data.sid));
 201                 goto fail;
 202         }
 203 
 204         if ( (type!=SID_NAME_USER) && (type!=SID_NAME_COMPUTER) ) {
 205                 DEBUG(5,("sid2uid_lookupsid_recv: Sid %s is not a user or a computer.\n", 
 206                          state->request.data.sid));
 207                 goto fail;
 208         }
 209 
 210         /* always use the async interface (may block) */
 211         winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
 212         return;
 213 
 214  fail:
 215         /*
 216          * We have to set the cache ourselves here, the child which is
 217          * normally responsible was not queried yet.
 218          */
 219         idmap_cache_set_sid2uid(&sid, -1);
 220         request_error(state);
 221         return;
 222 }
 223 
 224 void winbindd_sid_to_uid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226         DOM_SID sid;
 227         uid_t uid;
 228         bool expired;
 229 
 230         /* Ensure null termination */
 231         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
 232 
 233         DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
 234                   state->request.data.sid));
 235 
 236         if (!string_to_sid(&sid, state->request.data.sid)) {
 237                 DEBUG(1, ("Could not get convert sid %s from string\n",
 238                           state->request.data.sid));
 239                 request_error(state);
 240                 return;
 241         }
 242 
 243         if (idmap_cache_find_sid2uid(&sid, &uid, &expired)) {
 244                 DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
 245                            (int)uid, expired ? " (expired)": ""));
 246                 if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
 247                         DEBUG(10, ("revalidating expired entry\n"));
 248                         goto backend;
 249                 }
 250                 if (uid == -1) {
 251                         DEBUG(10, ("Returning negative cache entry\n"));
 252                         request_error(state);
 253                         return;
 254                 }
 255                 DEBUG(10, ("Returning positive cache entry\n"));
 256                 state->response.data.uid = uid;
 257                 request_ok(state);
 258                 return;
 259         }
 260 
 261         /* Validate the SID as a user.  Hopefully this will hit cache.
 262            Needed to prevent DoS by exhausting the uid allocation
 263            range from random SIDs. */
 264 
 265  backend:
 266         winbindd_lookupsid_async( state->mem_ctx, &sid, sid2uid_lookupsid_recv, state );
 267 }
 268 
 269 /* Convert a sid to a gid.  We assume we only have one rid attached to the
 270    sid.*/
 271 
 272 static void sid2gid_recv(void *private_data, bool success, gid_t gid)
     /* [<][>][^][v][top][bottom][index][help] */
 273 {
 274         struct winbindd_cli_state *state =
 275                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 276         struct dom_sid sid;
 277 
 278         string_to_sid(&sid, state->request.data.sid);
 279 
 280         if (!success) {
 281                 DEBUG(5, ("Could not convert sid %s\n",
 282                           state->request.data.sid));
 283                 request_error(state);
 284                 return;
 285         }
 286 
 287         state->response.data.gid = gid;
 288         request_ok(state);
 289 }
 290 
 291 static void sid2gid_lookupsid_recv( void *private_data, bool success, 
     /* [<][>][^][v][top][bottom][index][help] */
 292                                     const char *domain_name, 
 293                                     const char *name, 
 294                                     enum lsa_SidType type)
 295 {
 296         struct winbindd_cli_state *state =
 297                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 298         DOM_SID sid;
 299 
 300         if (!string_to_sid(&sid, state->request.data.sid)) {
 301                 DEBUG(1, ("sid2gid_lookupsid_recv: Could not get convert sid "
 302                           "%s from string\n", state->request.data.sid));
 303                 request_error(state);
 304                 return;
 305         }
 306 
 307         if (!success) {
 308                 DEBUG(5, ("sid2gid_lookupsid_recv: Could not get sid type for %s\n",
 309                           state->request.data.sid));
 310                 goto fail;
 311         }
 312 
 313         if ( (type!=SID_NAME_DOM_GRP) &&
 314              (type!=SID_NAME_ALIAS) && 
 315              (type!=SID_NAME_WKN_GRP) ) 
 316         {
 317                 DEBUG(5,("sid2gid_lookupsid_recv: Sid %s is not a group.\n", 
 318                          state->request.data.sid));
 319                 goto fail;
 320         }
 321 
 322         /* always use the async interface (may block) */
 323         winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
 324         return;
 325 
 326  fail:
 327         /*
 328          * We have to set the cache ourselves here, the child which is
 329          * normally responsible was not queried yet.
 330          */
 331         idmap_cache_set_sid2gid(&sid, -1);
 332         request_error(state);
 333         return;
 334 }
 335 
 336 void winbindd_sid_to_gid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 337 {
 338         DOM_SID sid;
 339         gid_t gid;
 340         bool expired;
 341 
 342         /* Ensure null termination */
 343         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
 344 
 345         DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
 346                   state->request.data.sid));
 347 
 348         if (!string_to_sid(&sid, state->request.data.sid)) {
 349                 DEBUG(1, ("Could not get convert sid %s from string\n",
 350                           state->request.data.sid));
 351                 request_error(state);
 352                 return;
 353         }
 354 
 355         if (idmap_cache_find_sid2gid(&sid, &gid, &expired)) {
 356                 DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
 357                            (int)gid, expired ? " (expired)": ""));
 358                 if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
 359                         DEBUG(10, ("revalidating expired entry\n"));
 360                         goto backend;
 361                 }
 362                 if (gid == -1) {
 363                         DEBUG(10, ("Returning negative cache entry\n"));
 364                         request_error(state);
 365                         return;
 366                 }
 367                 DEBUG(10, ("Returning positive cache entry\n"));
 368                 state->response.data.gid = gid;
 369                 request_ok(state);
 370                 return;
 371         }
 372 
 373         /* Validate the SID as a group.  Hopefully this will hit cache.
 374            Needed to prevent DoS by exhausting the uid allocation
 375            range from random SIDs. */
 376 
 377  backend:
 378         winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv,
 379                                   state );
 380 }
 381 
 382 static void set_mapping_recv(void *private_data, bool success)
     /* [<][>][^][v][top][bottom][index][help] */
 383 {
 384         struct winbindd_cli_state *state =
 385                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 386 
 387         if (!success) {
 388                 DEBUG(5, ("Could not set sid mapping\n"));
 389                 request_error(state);
 390                 return;
 391         }
 392 
 393         request_ok(state);
 394 }
 395 
 396 void winbindd_set_mapping(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 397 {
 398         struct id_map map;
 399         DOM_SID sid;
 400 
 401         DEBUG(3, ("[%5lu]: set id map\n", (unsigned long)state->pid));
 402 
 403         if ( ! state->privileged) {
 404                 DEBUG(0, ("Only root is allowed to set mappings!\n"));
 405                 request_error(state);
 406                 return;
 407         }
 408 
 409         if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid)) {
 410                 DEBUG(1, ("Could not get convert sid %s from string\n",
 411                           state->request.data.sid));
 412                 request_error(state);
 413                 return;
 414         }
 415 
 416         map.sid = &sid;
 417         map.xid.id = state->request.data.dual_idmapset.id;
 418         map.xid.type = state->request.data.dual_idmapset.type;
 419 
 420         winbindd_set_mapping_async(state->mem_ctx, &map,
 421                         set_mapping_recv, state);
 422 }
 423 
 424 static void remove_mapping_recv(void *private_data, bool success)
     /* [<][>][^][v][top][bottom][index][help] */
 425 {
 426         struct winbindd_cli_state *state =
 427                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 428 
 429         if (!success) {
 430                 DEBUG(5, ("Could not remove sid mapping\n"));
 431                 request_error(state);
 432                 return;
 433         }
 434 
 435         request_ok(state);
 436 }
 437 
 438 void winbindd_remove_mapping(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 439 {
 440         struct id_map map;
 441         DOM_SID sid;
 442 
 443         DEBUG(3, ("[%5lu]: remove id map\n", (unsigned long)state->pid));
 444 
 445         if ( ! state->privileged) {
 446                 DEBUG(0, ("Only root is allowed to remove mappings!\n"));
 447                 request_error(state);
 448                 return;
 449         }
 450 
 451         if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid)) {
 452                 DEBUG(1, ("Could not get convert sid %s from string\n",
 453                           state->request.data.sid));
 454                 request_error(state);
 455                 return;
 456         }
 457 
 458         map.sid = &sid;
 459         map.xid.id = state->request.data.dual_idmapset.id;
 460         map.xid.type = state->request.data.dual_idmapset.type;
 461 
 462         winbindd_remove_mapping_async(state->mem_ctx, &map,
 463                         remove_mapping_recv, state);
 464 }
 465 
 466 static void set_hwm_recv(void *private_data, bool success)
     /* [<][>][^][v][top][bottom][index][help] */
 467 {
 468         struct winbindd_cli_state *state =
 469                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
 470 
 471         if (!success) {
 472                 DEBUG(5, ("Could not set sid mapping\n"));
 473                 request_error(state);
 474                 return;
 475         }
 476 
 477         request_ok(state);
 478 }
 479 
 480 void winbindd_set_hwm(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 481 {
 482         struct unixid xid;
 483 
 484         DEBUG(3, ("[%5lu]: set hwm\n", (unsigned long)state->pid));
 485 
 486         if ( ! state->privileged) {
 487                 DEBUG(0, ("Only root is allowed to set mappings!\n"));
 488                 request_error(state);
 489                 return;
 490         }
 491 
 492         xid.id = state->request.data.dual_idmapset.id;
 493         xid.type = state->request.data.dual_idmapset.type;
 494 
 495         winbindd_set_hwm_async(state->mem_ctx, &xid, set_hwm_recv, state);
 496 }
 497 
 498 /* Convert a uid to a sid */
 499 
 500 static void uid2sid_recv(void *private_data, bool success, const char *sidstr)
     /* [<][>][^][v][top][bottom][index][help] */
 501 {
 502         struct winbindd_cli_state *state =
 503                 (struct winbindd_cli_state *)private_data;
 504         struct dom_sid sid;
 505 
 506         if (!success || !string_to_sid(&sid, sidstr)) {
 507                 ZERO_STRUCT(sid);
 508                 idmap_cache_set_sid2uid(&sid, state->request.data.uid);
 509                 request_error(state);
 510                 return;
 511         }
 512 
 513         DEBUG(10,("uid2sid: uid %lu has sid %s\n",
 514                   (unsigned long)(state->request.data.uid), sidstr));
 515 
 516         idmap_cache_set_sid2uid(&sid, state->request.data.uid);
 517         fstrcpy(state->response.data.sid.sid, sidstr);
 518         state->response.data.sid.type = SID_NAME_USER;
 519         request_ok(state);
 520         return;
 521 }
 522 
 523 void winbindd_uid_to_sid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 524 {
 525         struct dom_sid sid;
 526         bool expired;
 527 
 528         DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid, 
 529                   (unsigned long)state->request.data.uid));
 530 
 531         if (idmap_cache_find_uid2sid(state->request.data.uid, &sid,
 532                                      &expired)) {
 533                 DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n",
 534                            (int)state->request.data.uid,
 535                            expired ? " (expired)": ""));
 536                 if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
 537                         DEBUG(10, ("revalidating expired entry\n"));
 538                         goto backend;
 539                 }
 540                 if (is_null_sid(&sid)) {
 541                         DEBUG(10, ("Returning negative cache entry\n"));
 542                         request_error(state);
 543                         return;
 544                 }
 545                 DEBUG(10, ("Returning positive cache entry\n"));
 546                 sid_to_fstring(state->response.data.sid.sid, &sid);
 547                 request_ok(state);
 548                 return;
 549         }
 550 
 551         /* always go via the async interface (may block) */
 552  backend:
 553         winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, uid2sid_recv, state);
 554 }
 555 
 556 /* Convert a gid to a sid */
 557 
 558 static void gid2sid_recv(void *private_data, bool success, const char *sidstr)
     /* [<][>][^][v][top][bottom][index][help] */
 559 {
 560         struct winbindd_cli_state *state =
 561                 (struct winbindd_cli_state *)private_data;
 562         struct dom_sid sid;
 563 
 564         if (!success || !string_to_sid(&sid, sidstr)) {
 565                 ZERO_STRUCT(sid);
 566                 idmap_cache_set_sid2gid(&sid, state->request.data.gid);
 567                 request_error(state);
 568                 return;
 569         }
 570         DEBUG(10,("gid2sid: gid %lu has sid %s\n",
 571                   (unsigned long)(state->request.data.gid), sidstr));
 572 
 573         idmap_cache_set_sid2gid(&sid, state->request.data.gid);
 574         fstrcpy(state->response.data.sid.sid, sidstr);
 575         state->response.data.sid.type = SID_NAME_DOM_GRP;
 576         request_ok(state);
 577         return;
 578 }
 579 
 580 
 581 void winbindd_gid_to_sid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 582 {
 583         struct dom_sid sid;
 584         bool expired;
 585 
 586         DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid, 
 587                   (unsigned long)state->request.data.gid));
 588 
 589         if (idmap_cache_find_gid2sid(state->request.data.gid, &sid,
 590                                      &expired)) {
 591                 DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n",
 592                            (int)state->request.data.gid,
 593                            expired ? " (expired)": ""));
 594                 if (expired && IS_DOMAIN_ONLINE(find_our_domain())) {
 595                         DEBUG(10, ("revalidating expired entry\n"));
 596                         goto backend;
 597                 }
 598                 if (is_null_sid(&sid)) {
 599                         DEBUG(10, ("Returning negative cache entry\n"));
 600                         request_error(state);
 601                         return;
 602                 }
 603                 DEBUG(10, ("Returning positive cache entry\n"));
 604                 sid_to_fstring(state->response.data.sid.sid, &sid);
 605                 request_ok(state);
 606                 return;
 607         }
 608 
 609         /* always use async calls (may block) */
 610  backend:
 611         winbindd_gid2sid_async(state->mem_ctx, state->request.data.gid, gid2sid_recv, state);
 612 }
 613 
 614 void winbindd_allocate_uid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 615 {
 616         if ( !state->privileged ) {
 617                 DEBUG(2, ("winbindd_allocate_uid: non-privileged access "
 618                           "denied!\n"));
 619                 request_error(state);
 620                 return;
 621         }
 622 
 623         sendto_child(state, idmap_child());
 624 }
 625 
 626 enum winbindd_result winbindd_dual_allocate_uid(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 627                                                 struct winbindd_cli_state *state)
 628 {
 629         struct unixid xid;
 630 
 631         if (!NT_STATUS_IS_OK(idmap_allocate_uid(&xid))) {
 632                 return WINBINDD_ERROR;
 633         }
 634         state->response.data.uid = xid.id;
 635         return WINBINDD_OK;
 636 }
 637 
 638 void winbindd_allocate_gid(struct winbindd_cli_state *state)
     /* [<][>][^][v][top][bottom][index][help] */
 639 {
 640         if ( !state->privileged ) {
 641                 DEBUG(2, ("winbindd_allocate_gid: non-privileged access "
 642                           "denied!\n"));
 643                 request_error(state);
 644                 return;
 645         }
 646 
 647         sendto_child(state, idmap_child());
 648 }
 649 
 650 enum winbindd_result winbindd_dual_allocate_gid(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 651                                                 struct winbindd_cli_state *state)
 652 {
 653         struct unixid xid;
 654 
 655         if (!NT_STATUS_IS_OK(idmap_allocate_gid(&xid))) {
 656                 return WINBINDD_ERROR;
 657         }
 658         state->response.data.gid = xid.id;
 659         return WINBINDD_OK;
 660 }

/* [<][>][^][v][top][bottom][index][help] */