wbclient.c

Go to the documentation of this file.
00001 /*
00002    Unix SMB/CIFS implementation.
00003 
00004    Winbind client API
00005 
00006    Copyright (C) Gerald (Jerry) Carter 2007
00007 
00008 
00009    This library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Lesser General Public
00011    License as published by the Free Software Foundation; either
00012    version 3 of the License, or (at your option) any later version.
00013 
00014    This library is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017    Library General Public License for more details.
00018 
00019    You should have received a copy of the GNU Lesser General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 
00023 /* Required Headers */
00024 
00025 #include "nsswitch/winbind_nss_config.h"
00026 #include "nsswitch/winbindd_nss.h"
00027 #include "wbclient.h"
00028 
00029 #define BAIL_ON_WBC_ERROR(x)  do { if ((x) != WBC_ERR_SUCCESS) goto fail; } while(0);
00030 
00031 /* From wb_common.c */
00032 
00033 NSS_STATUS winbindd_request_response(int req_type,
00034                                      struct winbindd_request *request,
00035                                      struct winbindd_response *response);
00036 
00037 /** @brief Convert a binary SID to a character string
00038  *
00039  * @param sid           Binary Security Identifier
00040  * @param **sid_string  Resulting character string
00041  *
00042  * @return #wbcErr
00043  **/
00044 
00045 wbcErr wbcSidToString(const struct wbcDomainSid *sid,
00046                       char **sid_string)
00047 {
00048         char tmp[256];
00049         char tmp2[32];
00050         uint32_t id_auth;
00051         int len, i;
00052         char *p;
00053 
00054         if (!sid)
00055                 return WBC_ERR_INVALID_SID;
00056 
00057         id_auth = sid->id_auth[5] +
00058                 (sid->id_auth[4] << 8) +
00059                 (sid->id_auth[3] << 16) +
00060                 (sid->id_auth[2] << 24);
00061 
00062         snprintf(tmp, sizeof(tmp)-1, "S-%d-%d", sid->sid_rev_num, id_auth );
00063 
00064         len = sizeof(tmp) - strlen(tmp);
00065         p = &tmp[sizeof(tmp)-len];
00066 
00067         for (i=0; i<sid->num_auths && len>0; i++) {
00068                 snprintf(tmp2, sizeof(tmp2)-1, "-%u", sid->sub_auths[i]);
00069                 strncat(p, tmp2, len-1);
00070 
00071                 len = sizeof(tmp) - strlen(tmp);
00072                 p = &tmp[sizeof(tmp)-len];
00073         }
00074 
00075         /* Did we run out of space? */
00076 
00077         if ((len==0) && (i<=sid->num_auths)) {
00078                 return WBC_ERR_NO_MEMORY;
00079         }
00080 
00081         if ((*sid_string=strdup(tmp)) == NULL ) {
00082                 return WBC_ERR_NO_MEMORY;
00083         }
00084 
00085         return WBC_ERR_SUCCESS;
00086 }
00087 
00088 /** @brief Convert a character string to a binary SID
00089  *
00090  * @param *str          Character string in the form of S-...
00091  * @param sid           Resulting binary SID
00092  *
00093  * @return #wbcErr
00094  **/
00095 
00096 wbcErr wbcStringToSid(const char *str,
00097                       struct wbcDomainSid *sid)
00098 {
00099         const char *p;
00100         char *q;
00101         uint32_t x;
00102 
00103         if (!sid)
00104                 return WBC_ERR_INVALID_PARAM;
00105 
00106         /* Sanity check for either "S-" or "s-" */
00107 
00108         if (!str
00109             || (str[0]!='S' && str[0]!='s')
00110             || (str[1]!='-')
00111             || (strlen(str)<2))
00112         {
00113                 return WBC_ERR_INVALID_SID;
00114         }
00115 
00116         /* Get the SID revision number */
00117 
00118         p = str+2;
00119         x = (uint32_t)strtol(p, &q, 10);
00120         if (x==0 || !q || *q!='-')
00121                 return WBC_ERR_INVALID_SID;
00122         sid->sid_rev_num = (uint8_t)x;
00123 
00124         /* Next the Identifier Authority.  This is stored in big-endian
00125            in a 6 byte array. */
00126 
00127         p = q+1;
00128         x = (uint32_t)strtol(p, &q, 10);
00129         if (x==0 || !q || *q!='-')
00130                 return WBC_ERR_INVALID_SID;
00131         sid->id_auth[5] = (x & 0x000000ff);
00132         sid->id_auth[4] = (x & 0x0000ff00) >> 8;
00133         sid->id_auth[3] = (x & 0x00ff0000) >> 16;
00134         sid->id_auth[2] = (x & 0xff000000) >> 24;
00135         sid->id_auth[1] = 0;
00136         sid->id_auth[0] = 0;
00137 
00138         /* now read the the subauthorities */
00139 
00140         p = q +1;
00141         sid->num_auths = 0;
00142         while (sid->num_auths < MAXSUBAUTHS) {
00143                 if ((x=(uint32_t)strtoul(p, &q, 10)) == 0)
00144                         break;
00145                 sid->sub_auths[sid->num_auths++] = x;
00146 
00147                 if (q && ((*q!='-') || (*q=='\0')))
00148                         break;
00149                 p = q + 1;
00150         }
00151 
00152         /* IF we ended early, then the SID could not be converted */
00153 
00154         if (q && *q!='\0')
00155                 return WBC_ERR_INVALID_SID;
00156 
00157         return WBC_ERR_SUCCESS;
00158 }
00159 
00160 
00161 
00162 /** @brief Convert a domain and name to SID
00163  *
00164  * @param domain      Domain name (possibly "")
00165  * @param name        User or group name
00166  * @param *sid        Pointer to the resolved domain SID
00167  * @param *name_type  Pointet to the SID type
00168  *
00169  * @return #wbcErr
00170  *
00171  **/
00172 
00173 wbcErr wbcLookupName(const char *domain,
00174                      const char *name,
00175                      struct wbcDomainSid *sid,
00176                      enum wbcSidType *name_type)
00177 {
00178         struct winbindd_request request;
00179         struct winbindd_response response;
00180         NSS_STATUS result;
00181         wbcErr wbc_ret = WBC_ERR_UNKNOWN_FAILURE;
00182 
00183         if (!sid || !name_type)
00184                 return WBC_ERR_INVALID_PARAM;
00185 
00186         /* Initialize request */
00187 
00188         ZERO_STRUCT(request);
00189         ZERO_STRUCT(response);
00190 
00191         /* dst is already null terminated from the memset above */
00192 
00193         strncpy(request.data.name.dom_name, domain,
00194                 sizeof(request.data.name.dom_name)-1);
00195         strncpy(request.data.name.name, name,
00196                 sizeof(request.data.name.name)-1);
00197 
00198         result = winbindd_request_response(WINBINDD_LOOKUPNAME,
00199                                            &request,
00200                                            &response);
00201         if ( result != NSS_STATUS_SUCCESS) {
00202                 goto fail;
00203         }
00204 
00205         wbc_ret = wbcStringToSid(response.data.sid.sid, sid);
00206         BAIL_ON_WBC_ERROR(wbc_ret);
00207 
00208         *name_type = (enum wbcSidType)response.data.sid.type;
00209         wbc_ret = WBC_ERR_SUCCESS;
00210 
00211  fail:
00212         return wbc_ret;
00213 }
00214 
00215 /** @brief Convert a SID to a domain and name
00216  *
00217  * @param *sid        Pointer to the domain SID to be resolved
00218  * @param domain      Resolved Domain name (possibly "")
00219  * @param name        Resolved User or group name
00220  * @param *name_type  Pointet to the resolved SID type
00221  *
00222  * @return #wbcErr
00223  *
00224  **/
00225 
00226 wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
00227                     char **domain,
00228                     char **name,
00229                     enum wbcSidType *name_type)
00230 {
00231         struct winbindd_request request;
00232         struct winbindd_response response;
00233         NSS_STATUS result;
00234         wbcErr wbc_ret = WBC_ERR_UNKNOWN_FAILURE;
00235         char *sid_string = NULL;
00236 
00237         *domain = NULL;
00238         *name = NULL;
00239 
00240         /* Initialize request */
00241 
00242         ZERO_STRUCT(request);
00243         ZERO_STRUCT(response);
00244 
00245         /* dst is already null terminated from the memset above */
00246 
00247         wbc_ret = wbcSidToString(sid, &sid_string);
00248         BAIL_ON_WBC_ERROR(wbc_ret);
00249 
00250         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
00251         free(sid_string);
00252 
00253         /* Make request */
00254 
00255         result = winbindd_request_response(WINBINDD_LOOKUPSID,
00256                                            &request,
00257                                            &response);
00258 
00259         if (result != NSS_STATUS_SUCCESS) {
00260                 goto fail;
00261         }
00262 
00263         /* Copy out result */
00264 
00265         if (domain != NULL) {
00266                 if ((*domain = strdup(response.data.name.dom_name)) == NULL) {
00267                         wbc_ret = WBC_ERR_NO_MEMORY;
00268                         BAIL_ON_WBC_ERROR(wbc_ret);
00269                 }
00270         }
00271 
00272         if (name != NULL) {
00273                 if ((*name = strdup(response.data.name.name)) == NULL) {
00274                         wbc_ret = WBC_ERR_NO_MEMORY;
00275                         BAIL_ON_WBC_ERROR(wbc_ret);
00276                 }
00277         }
00278 
00279         if (name_type)
00280                 *name_type = (enum wbcSidType)response.data.name.type;
00281 
00282         wbc_ret = WBC_ERR_SUCCESS;
00283 
00284  fail:
00285         if (wbc_ret != WBC_ERR_SUCCESS) {
00286                 if (*domain)
00287                         free(*domain);
00288                 if (*name)
00289                         free(*name);
00290         }
00291 
00292         return wbc_ret;
00293 }
00294 
00295 /** @brief Convert a Windows SID to a Unix uid
00296  *
00297  * @param *sid        Pointer to the domain SID to be resolved
00298  * @param *puid       Pointer to the resolved uid_t value
00299  *
00300  * @return #wbcErr
00301  *
00302  **/
00303 
00304 wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
00305 {
00306         struct winbindd_request request;
00307         struct winbindd_response response;
00308         NSS_STATUS result;
00309         char *sid_string = NULL;
00310         wbcErr wbc_ret = WBC_ERR_UNKNOWN_FAILURE;
00311 
00312         if (!puid)
00313                 return 0;
00314 
00315         /* Initialize request */
00316 
00317         ZERO_STRUCT(request);
00318         ZERO_STRUCT(response);
00319 
00320         wbc_ret = wbcSidToString(sid, &sid_string);
00321         BAIL_ON_WBC_ERROR(wbc_ret);
00322 
00323         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
00324         free(sid_string);
00325 
00326         /* Make request */
00327 
00328         result = winbindd_request_response(WINBINDD_SID_TO_UID,
00329                                            &request,
00330                                            &response);
00331 
00332         /* Copy out result */
00333 
00334         if (result != NSS_STATUS_SUCCESS) {
00335                 return WBC_ERR_UNKNOWN_FAILURE;
00336         }
00337 
00338         *puid = response.data.uid;
00339         wbc_ret = WBC_ERR_SUCCESS;
00340 
00341  fail:
00342         return wbc_ret;
00343 }
00344 
00345 /** @brief Convert a Unix uid to a Windows SID
00346  *
00347  * @param uid         Unix uid to be resolved
00348  * @param *sid        Pointer to the resolved domain SID
00349  *
00350  * @return #wbcErr
00351  *
00352  **/
00353 
00354 wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid)
00355 {
00356         struct winbindd_request request;
00357         struct winbindd_response response;
00358         NSS_STATUS result;
00359 
00360         if (!sid)
00361                 return False;
00362 
00363         /* Initialize request */
00364 
00365         ZERO_STRUCT(request);
00366         ZERO_STRUCT(response);
00367 
00368         request.data.uid = uid;
00369 
00370         /* Make request */
00371 
00372         result = winbindd_request_response(WINBINDD_UID_TO_SID,
00373                                            &request,
00374                                            &response);
00375 
00376         /* Copy out result */
00377 
00378         if (result != NSS_STATUS_SUCCESS) {
00379                 return WBC_ERR_UNKNOWN_FAILURE;
00380         }
00381 
00382         return wbcStringToSid(response.data.sid.sid, sid);
00383 }
00384 
00385 /** @brief Convert a Windows SID to a Unix gid
00386  *
00387  * @param *sid        Pointer to the domain SID to be resolved
00388  * @param *pgid       Pointer to the resolved gid_t value
00389  *
00390  * @return #wbcErr
00391  *
00392  **/
00393 
00394 wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
00395 {
00396         struct winbindd_request request;
00397         struct winbindd_response response;
00398         NSS_STATUS result;
00399         wbcErr wbc_ret = WBC_ERR_UNKNOWN_FAILURE;
00400         char *sid_string = NULL;
00401 
00402         if (!pgid)
00403                 return False;
00404 
00405         /* Initialize request */
00406 
00407         ZERO_STRUCT(request);
00408         ZERO_STRUCT(response);
00409 
00410         wbc_ret = wbcSidToString(sid, &sid_string);
00411         BAIL_ON_WBC_ERROR(wbc_ret);
00412 
00413         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
00414         free(sid_string);
00415 
00416         /* Make request */
00417 
00418         result = winbindd_request_response(WINBINDD_SID_TO_GID,
00419                                            &request,
00420                                            &response);
00421 
00422         /* Copy out result */
00423 
00424         if (result != NSS_STATUS_SUCCESS) {
00425                 return WBC_ERR_UNKNOWN_FAILURE;
00426         }
00427 
00428         *pgid = response.data.gid;
00429         wbc_ret = WBC_ERR_SUCCESS;
00430 
00431  fail:
00432         return wbc_ret;
00433 }
00434 
00435 /** @brief Convert a Unix uid to a Windows SID
00436  *
00437  * @param gid         Unix gid to be resolved
00438  * @param *sid        Pointer to the resolved domain SID
00439  *
00440  * @return #wbcErr
00441  *
00442  **/
00443 
00444 wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
00445 {
00446         struct winbindd_request request;
00447         struct winbindd_response response;
00448         NSS_STATUS result;
00449 
00450         if (!sid)
00451                 return False;
00452 
00453         /* Initialize request */
00454 
00455         ZERO_STRUCT(request);
00456         ZERO_STRUCT(response);
00457 
00458         request.data.gid = gid;
00459 
00460         /* Make request */
00461 
00462         result = winbindd_request_response(WINBINDD_GID_TO_SID,
00463                                            &request,
00464                                            &response);
00465 
00466 
00467         /* Copy out result */
00468 
00469         if (result != NSS_STATUS_SUCCESS) {
00470                 return WBC_ERR_UNKNOWN_FAILURE;
00471         }
00472 
00473         return wbcStringToSid(response.data.sid.sid, sid);
00474 }
00475 
00476 /** @brief Ping winbindd to see if the daemon is running
00477  *
00478  * @return #wbcErr
00479  **/
00480 
00481 wbcErr wbcPing(void)
00482 {
00483         NSS_STATUS result;
00484 
00485         result = winbindd_request_response(WINBINDD_PING, NULL, NULL);
00486 
00487         if (result != NSS_STATUS_SUCCESS)
00488                 return WBC_ERR_UNKNOWN_FAILURE;
00489         
00490         return WBC_ERR_SUCCESS; 
00491 }
00492 
00493 /** @brief Lookup the current status of a trusted domain
00494  *
00495  * @param domain      Domain to query
00496  * @param *info       Pointer to returned domain_info struct
00497  *
00498  * @return #wbcErr
00499  *
00500  * The char* members of the struct wbcDomainInfo* are malloc()'d
00501  * and it the the responsibility of the caller to free the members
00502  * before  discarding the struct.
00503  *
00504  **/
00505 
00506 /**********************************************************************
00507  result == NSS_STATUS_UNAVAIL: winbind not around
00508  result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
00509 
00510  Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off 
00511  and when winbind return WINBINDD_ERROR. So the semantics of this 
00512  routine depends on winbind_on. Grepping for winbind_off I just 
00513  found 3 places where winbind is turned off, and this does not conflict 
00514  (as far as I have seen) with the callers of is_trusted_domains.   
00515 
00516  --Volker
00517 **********************************************************************/
00518 
00519 wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo *info)
00520 {
00521         struct winbindd_request request;
00522         struct winbindd_response response;
00523         NSS_STATUS result;
00524         wbcErr ret;
00525         
00526         if (!domain || !info)
00527                 return WBC_ERR_INVALID_PARAM;
00528 
00529         ZERO_STRUCT(*info);
00530         
00531         /* Initialize request */
00532 
00533         ZERO_STRUCT(request);
00534         ZERO_STRUCT(response);
00535 
00536         strncpy(request.domain_name, domain, sizeof(request.domain_name)-1);    
00537 
00538         result = winbindd_request_response(WINBINDD_DOMAIN_INFO,
00539                                            &request,
00540                                            &response);
00541 
00542         /* Copy out result */
00543 
00544         if (result != NSS_STATUS_SUCCESS) {
00545                 switch(result){
00546                 case NSS_STATUS_UNAVAIL:
00547                         return WBC_ERR_WINBIND_NOT_AVAILABLE;
00548                         break;
00549                 case NSS_STATUS_NOTFOUND:
00550                         return WBC_ERR_DOMAIN_NOT_FOUND;
00551                         break;                  
00552                 default:
00553                         return WBC_ERR_UNKNOWN_FAILURE;
00554                 }               
00555         }
00556 
00557         info->short_name = strdup(response.data.domain_info.name);
00558         info->dns_name   = strdup(response.data.domain_info.alt_name);
00559         if (!info->short_name || !info->dns_name) {             
00560                 ret = WBC_ERR_NO_MEMORY;
00561                 BAIL_ON_WBC_ERROR(ret);
00562         }       
00563         
00564         ret = wbcStringToSid(response.data.domain_info.sid, &info->sid);
00565         BAIL_ON_WBC_ERROR(ret);
00566         
00567         if (response.data.domain_info.native_mode)
00568                 info->flags |= WBC_DOMINFO_NATIVE;
00569         if (response.data.domain_info.active_directory)
00570                 info->flags |= WBC_DOMINFO_AD;
00571         if (response.data.domain_info.primary)
00572                 info->flags |= WBC_DOMINFO_PRIMARY;
00573         
00574         info->seqnum = response.data.domain_info.sequence_number;       
00575 
00576         ret = WBC_ERR_SUCCESS;  
00577 
00578  fail:
00579         if (ret != WBC_ERR_SUCCESS) {
00580                 if (info->short_name)
00581                         free(info->short_name);
00582                 if (info->dns_name)
00583                         free(info->dns_name);
00584         }
00585         
00586         return ret;     
00587 }
00588 
00589 /** @brief Translate a collection of RIDs within a domain to names
00590  *
00591  **/
00592 
00593 wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, 
00594                      int num_rids, 
00595                      uint32_t *rids,
00596                      const char **domain_name,
00597                      const char ***names, 
00598                      enum wbcSidType **types)
00599 {
00600         size_t i, len, ridbuf_size;     
00601         char *ridlist;
00602         char *p;
00603         struct winbindd_request request;
00604         struct winbindd_response response;
00605         NSS_STATUS result;
00606         char *sid_string = NULL;        
00607         wbcErr ret;
00608 
00609         if (num_rids == 0) {
00610                 return WBC_ERR_INVALID_PARAM;
00611         }
00612 
00613         /* Initialise request */
00614 
00615         ZERO_STRUCT(request);
00616         ZERO_STRUCT(response);
00617 
00618         ret = wbcSidToString(dom_sid, &sid_string);
00619         BAIL_ON_WBC_ERROR(ret);
00620 
00621         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
00622 
00623         /* Even if all the Rids were of maximum 32bit values,
00624            we would only have 11 bytes per rid in the final array
00625            ("4294967296" + \n).  Add one more byte for the 
00626            terminating '\0' */
00627 
00628         ridbuf_size = (sizeof(char)*11) * num_rids + 1;
00629         if ((ridlist = malloc(ridbuf_size)) == NULL)
00630                 return WBC_ERR_NO_MEMORY;
00631         memset(ridlist, 0x0, ridbuf_size);      
00632 
00633         len = 0;
00634         for (i=0; i<num_rids && (len-1)>0; i++) {
00635                 char ridstr[12];
00636                 
00637                 len = strlen(ridlist);
00638                 p = ridlist + len;
00639                 
00640                 snprintf( ridstr, sizeof(ridstr)-1, "%u\n", rids[i]);
00641                 strncat(p, ridstr, ridbuf_size-len-1);
00642         }
00643 
00644         request.extra_data.data = ridlist;
00645         request.extra_len = strlen(ridlist)+1;
00646 
00647         result = winbindd_request_response(WINBINDD_LOOKUPRIDS,
00648                                            &request, &response);
00649 
00650         free(ridlist);  
00651 
00652         if (result != NSS_STATUS_SUCCESS) {
00653                 return WBC_ERR_UNKNOWN_FAILURE;
00654         }
00655 
00656         *domain_name = strdup(response.data.domain_name);
00657 
00658         *names = (const char**)malloc(sizeof(char*) * num_rids);
00659         *types = (enum wbcSidType*)malloc(sizeof(enum wbcSidType) * num_rids);
00660 
00661         if (!*names || !*types) {
00662                 ret = WBC_ERR_NO_MEMORY;
00663                 BAIL_ON_WBC_ERROR(ret);
00664         }
00665         
00666         p = (char *)response.extra_data.data;
00667 
00668         for (i=0; i<num_rids; i++) {
00669                 char *q;
00670 
00671                 if (*p == '\0') {
00672                         ret = WCB_INVALID_RESPONSE;
00673                         BAIL_ON_WBC_ERROR(ret);
00674                 }
00675                         
00676                 (*types)[i] = (enum wbcSidType)strtoul(p, &q, 10);
00677 
00678                 if (*q != ' ') {
00679                         ret = WCB_INVALID_RESPONSE;
00680                         BAIL_ON_WBC_ERROR(ret);
00681                 }
00682 
00683                 p = q+1;
00684 
00685                 if ((q = strchr(p, '\n')) == NULL) {
00686                         ret = WCB_INVALID_RESPONSE;
00687                         BAIL_ON_WBC_ERROR(ret);
00688                 }
00689 
00690                 *q = '\0';
00691 
00692                 (*names)[i] = strdup(p);
00693 
00694                 p = q+1;
00695         }
00696 
00697         if (*p != '\0') {
00698                 ret = WCB_INVALID_RESPONSE;
00699                 BAIL_ON_WBC_ERROR(ret);
00700         }
00701 
00702         free(response.extra_data.data);
00703 
00704         ret = WBC_ERR_SUCCESS;
00705 
00706  fail:
00707         if (ret != WBC_ERR_SUCCESS) {
00708                 if (*domain_name)
00709                         free(*domain_name);
00710                 if (*names)
00711                         free(*names);
00712                 if (*types)
00713                         free(*types);
00714         }
00715 
00716         return ret;
00717 }
00718 
00719 /** @brief Obtain a new uid from Winbind
00720  *
00721  * @param *puid      *pointer to the allocated uid
00722  *
00723  * @return #wbcErr
00724  **/
00725 
00726 wbcErr wbcAllocateUid(uid_t *puid)
00727 {
00728         struct winbindd_request request;
00729         struct winbindd_response response;
00730         NSS_STATUS result;
00731 
00732         if (!puid)
00733                 return WBC_ERR_INVALID_PARAM;
00734         
00735         /* Initialise request */
00736 
00737         ZERO_STRUCT(request);
00738         ZERO_STRUCT(response);
00739 
00740         /* Make request */
00741 
00742         result = winbindd_request_response(WINBINDD_ALLOCATE_UID,
00743                                            &request, &response);
00744 
00745         if (result != NSS_STATUS_SUCCESS)
00746                 return WBC_ERR_UNKNOWN_FAILURE;
00747 
00748         /* Copy out result */
00749         *puid = response.data.uid;
00750 
00751         return WBC_ERR_SUCCESS;
00752 }
00753 
00754 /** @brief Obtain a new gid from Winbind
00755  *
00756  * @param *pgid      Pointer to the allocated gid
00757  *
00758  * @return #wbcErr
00759  **/
00760 
00761 wbcErr wbcAllocateGid(uid_t *pgid)
00762 {
00763         struct winbindd_request request;
00764         struct winbindd_response response;
00765         NSS_STATUS result;
00766 
00767         if (!pgid)
00768                 return WBC_ERR_INVALID_PARAM;
00769         
00770         /* Initialise request */
00771 
00772         ZERO_STRUCT(request);
00773         ZERO_STRUCT(response);
00774 
00775         /* Make request */
00776 
00777         result = winbindd_request_response(WINBINDD_ALLOCATE_GID,
00778                                            &request, &response);
00779 
00780         if (result != NSS_STATUS_SUCCESS)
00781                 return WBC_ERR_UNKNOWN_FAILURE;
00782 
00783         /* Copy out result */
00784         *pgid = response.data.gid;
00785 
00786         return WBC_ERR_SUCCESS;
00787 }
00788 

Generated on Fri Sep 7 16:31:10 2007 for Samba by  doxygen 1.5.0